From 0e1e4c79ea6a1f83cedea1d4286fb29507ca24eb Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Fri, 18 Nov 2022 04:37:24 -0500 Subject: [PATCH 001/101] [v9.3.x] OAuth: Refactor OAuth parameters handling to support obtaining refresh tokens for Google OAuth (#58940) OAuth: Refactor OAuth parameters handling to support obtaining refresh tokens for Google OAuth (#58782) * Add ApprovalForce to AuthCodeOptions * Extract access token validity check to a function * Refactor * Oauth: set options internally instead of exposing new function * Align tests * Remove unused function Co-authored-by: Karl Persson (cherry picked from commit 9c98314e9f9f488470eea88d6f596d7d4cf9ade3) Co-authored-by: Misi --- pkg/services/contexthandler/contexthandler.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pkg/services/contexthandler/contexthandler.go b/pkg/services/contexthandler/contexthandler.go index a30f560b41407..278461f232a3e 100644 --- a/pkg/services/contexthandler/contexthandler.go +++ b/pkg/services/contexthandler/contexthandler.go @@ -225,3 +225,16 @@ func AuthHTTPHeaderListFromContext(c context.Context) *AuthHTTPHeaderList { } return nil } + +func (h *ContextHandler) hasAccessTokenExpired(token *models.UserAuth) bool { + if token.OAuthExpiry.IsZero() { + return false + } + + getTime := h.GetTime + if getTime == nil { + getTime = time.Now + } + + return token.OAuthExpiry.Round(0).Add(-oauthtoken.ExpiryDelta).Before(getTime()) +} From f1f2ef28c929044d2d8cf8fbedf7b12d92984701 Mon Sep 17 00:00:00 2001 From: Joao Silva <100691367+JoaoSilvaGrafana@users.noreply.github.com> Date: Tue, 22 Nov 2022 17:45:52 +0100 Subject: [PATCH 002/101] [v9.3.x] Preferences: Add confirmation modal when saving org preferences (#59119) (#59141) --- public/app/features/org/OrgDetailsPage.test.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/app/features/org/OrgDetailsPage.test.tsx b/public/app/features/org/OrgDetailsPage.test.tsx index 0fc7ab9e728fd..07b6ad1152f98 100644 --- a/public/app/features/org/OrgDetailsPage.test.tsx +++ b/public/app/features/org/OrgDetailsPage.test.tsx @@ -4,6 +4,8 @@ import { mockToolkitActionCreator } from 'test/core/redux/mocks'; import { TestProvider } from 'test/helpers/TestProvider'; import { NavModel } from '@grafana/data'; +import { ModalManager } from 'app/core/services/ModalManager'; +import { configureStore } from 'app/store/configureStore'; import { backendSrv } from '../../core/services/backend_srv'; import { Organization } from '../../types'; From fa9a0501a83172d8191944ed572fb7c3c0f07f51 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Wed, 23 Nov 2022 10:26:55 +0000 Subject: [PATCH 003/101] =?UTF-8?q?Navigation:=20share=20logic=20between?= =?UTF-8?q?=20`buildBreadcrumbs`=20and=20`usePageTitle`=E2=80=A6=20(#59155?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Navigation: share logic between `buildBreadcrumbs` and `usePageTitle` (#58819) * simplify usePageTitle logic a bit * use buildBreadcrumbs logic in usePageTitle * always add home item to navTree, fix some tests * fix remaining unit tests (cherry picked from commit 824a562b03595fe02e7d140d600f4c94c0b5a8d5) --- public/app/core/navigation/GrafanaRoute.test.tsx | 1 + public/app/features/api-keys/ApiKeysPage.test.tsx | 2 ++ .../DashboardSettings/AnnotationsSettings.test.tsx | 2 ++ .../components/DashboardSettings/LinksSettings.test.tsx | 2 ++ public/app/features/invites/SignupInvited.test.tsx | 2 ++ public/app/features/org/OrgDetailsPage.test.tsx | 3 ++- public/app/features/playlist/PlaylistEditPage.test.tsx | 1 + public/app/features/playlist/PlaylistNewPage.test.tsx | 1 + public/app/features/playlist/PlaylistPage.test.tsx | 2 ++ public/app/features/profile/ChangePasswordPage.test.tsx | 2 ++ public/app/features/profile/UserProfileEditPage.test.tsx | 9 ++++++--- .../serviceaccounts/ServiceAccountCreatePage.test.tsx | 1 + .../features/serviceaccounts/ServiceAccountPage.test.tsx | 3 +++ .../serviceaccounts/ServiceAccountsListPage.test.tsx | 2 ++ public/app/features/teams/CreateTeam.test.tsx | 2 ++ public/app/features/teams/TeamList.test.tsx | 1 + 16 files changed, 32 insertions(+), 4 deletions(-) diff --git a/public/app/core/navigation/GrafanaRoute.test.tsx b/public/app/core/navigation/GrafanaRoute.test.tsx index 301ccdae9358e..2a267da60da33 100644 --- a/public/app/core/navigation/GrafanaRoute.test.tsx +++ b/public/app/core/navigation/GrafanaRoute.test.tsx @@ -12,6 +12,7 @@ import { GrafanaRoute, Props } from './GrafanaRoute'; import { GrafanaRouteComponentProps } from './types'; function setup(overrides: Partial) { + const store = configureStore(); const props: Props = { location: { search: '?query=hello&test=asd' } as Location, history: {} as History, diff --git a/public/app/features/api-keys/ApiKeysPage.test.tsx b/public/app/features/api-keys/ApiKeysPage.test.tsx index 728508a14e8c7..61fda18b90136 100644 --- a/public/app/features/api-keys/ApiKeysPage.test.tsx +++ b/public/app/features/api-keys/ApiKeysPage.test.tsx @@ -6,6 +6,7 @@ import { ApiKey, OrgRole } from 'app/types'; import { mockToolkitActionCreator } from '../../../test/core/redux/mocks'; import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput'; +import { configureStore } from '../../store/configureStore'; import { ApiKeysPageUnconnected, Props } from './ApiKeysPage'; import { getMultipleMockKeys } from './__mocks__/apiKeysMock'; @@ -21,6 +22,7 @@ jest.mock('app/core/core', () => { }); const setup = (propOverrides: Partial) => { + const store = configureStore(); const loadApiKeysMock = jest.fn(); const deleteApiKeyMock = jest.fn(); const migrateApiKeyMock = jest.fn(); diff --git a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx index 6bd55b389aa0e..1376480db8c94 100644 --- a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx @@ -5,12 +5,14 @@ import { TestProvider } from 'test/helpers/TestProvider'; import { locationService, setAngularLoader, setDataSourceSrv } from '@grafana/runtime'; import { mockDataSource, MockDataSourceSrv } from 'app/features/alerting/unified/mocks'; +import { configureStore } from '../../../../store/configureStore'; import { DashboardModel } from '../../state/DashboardModel'; import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures'; import { AnnotationsSettings } from './AnnotationsSettings'; function setup(dashboard: DashboardModel, editIndex?: number) { + const store = configureStore(); const sectionNav = { main: { text: 'Dashboard' }, node: { diff --git a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx index 21e7144ba45c1..0ce6336bc2275 100644 --- a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx @@ -2,12 +2,14 @@ import { screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { render } from 'test/test-utils'; +import { configureStore } from '../../../../store/configureStore'; import { DashboardModel } from '../../state'; import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures'; import { DashboardSettings } from './DashboardSettings'; function setup(dashboard: DashboardModel) { + const store = configureStore(); const sectionNav = { main: { text: 'Dashboard' }, node: { diff --git a/public/app/features/invites/SignupInvited.test.tsx b/public/app/features/invites/SignupInvited.test.tsx index f352df4e70174..4bcf51d820ac2 100644 --- a/public/app/features/invites/SignupInvited.test.tsx +++ b/public/app/features/invites/SignupInvited.test.tsx @@ -6,6 +6,7 @@ import { TestProvider } from 'test/helpers/TestProvider'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; import { backendSrv } from '../../core/services/backend_srv'; +import { configureStore } from '../../store/configureStore'; import { SignupInvitedPage, Props } from './SignupInvited'; @@ -29,6 +30,7 @@ const defaultGet = { async function setupTestContext({ get = defaultGet }: { get?: typeof defaultGet | null } = {}) { jest.clearAllMocks(); + const store = configureStore(); const getSpy = jest.spyOn(backendSrv, 'get'); getSpy.mockResolvedValue(get); diff --git a/public/app/features/org/OrgDetailsPage.test.tsx b/public/app/features/org/OrgDetailsPage.test.tsx index 07b6ad1152f98..c4d666c71c79c 100644 --- a/public/app/features/org/OrgDetailsPage.test.tsx +++ b/public/app/features/org/OrgDetailsPage.test.tsx @@ -5,9 +5,9 @@ import { TestProvider } from 'test/helpers/TestProvider'; import { NavModel } from '@grafana/data'; import { ModalManager } from 'app/core/services/ModalManager'; -import { configureStore } from 'app/store/configureStore'; import { backendSrv } from '../../core/services/backend_srv'; +import { configureStore } from '../../store/configureStore'; import { Organization } from '../../types'; import { OrgDetailsPage, Props } from './OrgDetailsPage'; @@ -23,6 +23,7 @@ jest.mock('app/core/core', () => { }); const setup = (propOverrides?: object) => { + const store = configureStore(); jest.clearAllMocks(); // needed because SharedPreferences is rendered in the test jest.spyOn(backendSrv, 'put'); diff --git a/public/app/features/playlist/PlaylistEditPage.test.tsx b/public/app/features/playlist/PlaylistEditPage.test.tsx index beda508e4f963..028691583d8f6 100644 --- a/public/app/features/playlist/PlaylistEditPage.test.tsx +++ b/public/app/features/playlist/PlaylistEditPage.test.tsx @@ -24,6 +24,7 @@ jest.mock('app/core/components/TagFilter/TagFilter', () => ({ async function getTestContext({ name, interval, items, uid }: Partial = {}) { jest.clearAllMocks(); + const store = configureStore(); const playlist = { name, items, interval, uid } as unknown as Playlist; const queryParams = {}; const route = {} as RouteDescriptor; diff --git a/public/app/features/playlist/PlaylistNewPage.test.tsx b/public/app/features/playlist/PlaylistNewPage.test.tsx index 46c549a02d6ac..3c55cf7e339f2 100644 --- a/public/app/features/playlist/PlaylistNewPage.test.tsx +++ b/public/app/features/playlist/PlaylistNewPage.test.tsx @@ -22,6 +22,7 @@ jest.mock('app/core/components/TagFilter/TagFilter', () => ({ })); function getTestContext({ name, interval, items }: Partial = {}) { + const store = configureStore(); jest.clearAllMocks(); const playlist = { name, items, interval } as unknown as Playlist; const backendSrvMock = jest.spyOn(backendSrv, 'post').mockImplementation(() => Promise.resolve()); diff --git a/public/app/features/playlist/PlaylistPage.test.tsx b/public/app/features/playlist/PlaylistPage.test.tsx index f538148d47c2c..b475c8a8946aa 100644 --- a/public/app/features/playlist/PlaylistPage.test.tsx +++ b/public/app/features/playlist/PlaylistPage.test.tsx @@ -3,6 +3,8 @@ import { TestProvider } from 'test/helpers/TestProvider'; import { contextSrv } from 'app/core/services/context_srv'; +import { configureStore } from '../../store/configureStore'; + import { PlaylistPage } from './PlaylistPage'; const fnMock = jest.fn(); diff --git a/public/app/features/profile/ChangePasswordPage.test.tsx b/public/app/features/profile/ChangePasswordPage.test.tsx index a807b8c4a1221..5d92cfbcd59cc 100644 --- a/public/app/features/profile/ChangePasswordPage.test.tsx +++ b/public/app/features/profile/ChangePasswordPage.test.tsx @@ -5,6 +5,7 @@ import { TestProvider } from 'test/helpers/TestProvider'; import config from 'app/core/config'; import { backendSrv } from '../../core/services/backend_srv'; +import { configureStore } from '../../store/configureStore'; import { Props, ChangePasswordPage } from './ChangePasswordPage'; import { initialUserState } from './state/reducers'; @@ -26,6 +27,7 @@ const defaultProps: Props = { }; async function getTestContext(overrides: Partial = {}) { + const store = configureStore(); jest.clearAllMocks(); jest.spyOn(backendSrv, 'get').mockResolvedValue({ id: 1, diff --git a/public/app/features/profile/UserProfileEditPage.test.tsx b/public/app/features/profile/UserProfileEditPage.test.tsx index a8e27dcd80db3..2f196e55765bf 100644 --- a/public/app/features/profile/UserProfileEditPage.test.tsx +++ b/public/app/features/profile/UserProfileEditPage.test.tsx @@ -8,6 +8,7 @@ import * as useQueryParams from 'app/core/hooks/useQueryParams'; import { TestProvider } from '../../../test/helpers/TestProvider'; import { backendSrv } from '../../core/services/backend_srv'; +import { configureStore } from '../../store/configureStore'; import { TeamPermissionLevel } from '../../types'; import { getMockTeam } from '../teams/__mocks__/teamMocks'; @@ -183,9 +184,11 @@ async function getTestContext(overrides: Partial - - + + + + + ); await waitFor(() => expect(props.initUserProfilePage).toHaveBeenCalledTimes(1)); diff --git a/public/app/features/serviceaccounts/ServiceAccountCreatePage.test.tsx b/public/app/features/serviceaccounts/ServiceAccountCreatePage.test.tsx index 346d79d6e4823..5f93130c65096 100644 --- a/public/app/features/serviceaccounts/ServiceAccountCreatePage.test.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountCreatePage.test.tsx @@ -44,6 +44,7 @@ jest.mock('app/core/core', () => ({ })); const setup = (propOverrides: Partial) => { + const store = configureStore(); const props: Props = { navModel: { main: { diff --git a/public/app/features/serviceaccounts/ServiceAccountPage.test.tsx b/public/app/features/serviceaccounts/ServiceAccountPage.test.tsx index e39d5c33daf63..6de68ad5a8be5 100644 --- a/public/app/features/serviceaccounts/ServiceAccountPage.test.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountPage.test.tsx @@ -6,6 +6,8 @@ import { TestProvider } from 'test/helpers/TestProvider'; import { RouteDescriptor } from 'app/core/navigation/types'; import { ApiKey, OrgRole, ServiceAccountDTO } from 'app/types'; +import { configureStore } from '../../store/configureStore'; + import { ServiceAccountPageUnconnected, Props } from './ServiceAccountPage'; jest.mock('app/core/core', () => ({ @@ -17,6 +19,7 @@ jest.mock('app/core/core', () => ({ })); const setup = (propOverrides: Partial) => { + const store = configureStore(); const createServiceAccountTokenMock = jest.fn(); const deleteServiceAccountMock = jest.fn(); const deleteServiceAccountTokenMock = jest.fn(); diff --git a/public/app/features/serviceaccounts/ServiceAccountsListPage.test.tsx b/public/app/features/serviceaccounts/ServiceAccountsListPage.test.tsx index 5276cd2026de2..b911ac64eb7a7 100644 --- a/public/app/features/serviceaccounts/ServiceAccountsListPage.test.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountsListPage.test.tsx @@ -4,6 +4,8 @@ import { TestProvider } from 'test/helpers/TestProvider'; import { OrgRole, ServiceAccountDTO, ServiceAccountStateFilter } from 'app/types'; +import { configureStore } from '../../store/configureStore'; + import { Props, ServiceAccountsListPageUnconnected } from './ServiceAccountsListPage'; jest.mock('app/core/core', () => ({ diff --git a/public/app/features/teams/CreateTeam.test.tsx b/public/app/features/teams/CreateTeam.test.tsx index bb219be7a71da..56364d07f3fe9 100644 --- a/public/app/features/teams/CreateTeam.test.tsx +++ b/public/app/features/teams/CreateTeam.test.tsx @@ -4,6 +4,8 @@ import { TestProvider } from 'test/helpers/TestProvider'; import { BackendSrv, setBackendSrv } from '@grafana/runtime'; +import { configureStore } from '../../store/configureStore'; + import { CreateTeam } from './CreateTeam'; beforeEach(() => { diff --git a/public/app/features/teams/TeamList.test.tsx b/public/app/features/teams/TeamList.test.tsx index 8f44409542414..28428380fcf56 100644 --- a/public/app/features/teams/TeamList.test.tsx +++ b/public/app/features/teams/TeamList.test.tsx @@ -17,6 +17,7 @@ jest.mock('app/core/core', () => ({ })); const setup = (propOverrides?: object) => { + const store = configureStore(); const props: Props = { teams: [] as Team[], noTeams: false, From e08d563f4dc659366ebd4fd8cc2cc419cee0711a Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Mon, 28 Nov 2022 14:21:34 +0100 Subject: [PATCH 004/101] [v9.3.x] CloudWatch: Cross-account querying support (#59389) * add cross-account querying support * fix tests --- .betterer.results | 2 +- .../metric_data_query_builder_test.go | 113 ++++++++++ pkg/tsdb/cloudwatch/models/api.go | 17 ++ pkg/tsdb/cloudwatch/services/logs.go | 53 +++++ pkg/tsdb/cloudwatch/services/logs_test.go | 200 ++++++++++++++++++ .../plugins/datasource/cloudwatch/Search.tsx | 39 ++++ .../cloudwatch/components/Account.test.tsx | 65 ++++++ .../cloudwatch/components/Account.tsx | 54 +++++ .../CrossAccountLogsQueryField.test.tsx | 190 +++++++++++++++++ .../components/CrossAccountLogsQueryField.tsx | 179 ++++++++++++++++ .../components/LogGroupSelection.test.tsx | 86 ++++++++ .../components/LogGroupSelection.tsx | 64 ++++++ .../cloudwatch/components/Search.test.tsx | 42 ++++ .../plugins/datasource/cloudwatch/hooks.ts | 1 + .../plugins/datasource/cloudwatch/tracking.ts | 3 + 15 files changed, 1107 insertions(+), 1 deletion(-) create mode 100644 pkg/tsdb/cloudwatch/services/logs.go create mode 100644 pkg/tsdb/cloudwatch/services/logs_test.go create mode 100644 public/app/plugins/datasource/cloudwatch/Search.tsx create mode 100644 public/app/plugins/datasource/cloudwatch/components/Account.test.tsx create mode 100644 public/app/plugins/datasource/cloudwatch/components/Account.tsx create mode 100644 public/app/plugins/datasource/cloudwatch/components/CrossAccountLogsQueryField.test.tsx create mode 100644 public/app/plugins/datasource/cloudwatch/components/CrossAccountLogsQueryField.tsx create mode 100644 public/app/plugins/datasource/cloudwatch/components/LogGroupSelection.test.tsx create mode 100644 public/app/plugins/datasource/cloudwatch/components/LogGroupSelection.tsx create mode 100644 public/app/plugins/datasource/cloudwatch/components/Search.test.tsx diff --git a/.betterer.results b/.betterer.results index f05cafeefa00a..06ec3c24f15a9 100644 --- a/.betterer.results +++ b/.betterer.results @@ -1,5 +1,5 @@ // BETTERER RESULTS V2. -// +// // If this file contains merge conflicts, use `betterer merge` to automatically resolve them: // https://phenomnomnominal.github.io/betterer/docs/results-file/#merge // diff --git a/pkg/tsdb/cloudwatch/metric_data_query_builder_test.go b/pkg/tsdb/cloudwatch/metric_data_query_builder_test.go index 907516f0d80d3..6f8922f3e8d91 100644 --- a/pkg/tsdb/cloudwatch/metric_data_query_builder_test.go +++ b/pkg/tsdb/cloudwatch/metric_data_query_builder_test.go @@ -264,6 +264,51 @@ func TestMetricDataQueryBuilder(t *testing.T) { assert.Equal(t, "${LABEL}|&|${PROP('Dim.InstanceId')}|&|${PROP('Dim.LoadBalancer')}", *mdq.Label) }) + t.Run("Query has multiple dimensions and an account Id", func(t *testing.T) { + query := &models.CloudWatchQuery{ + Namespace: "AWS/EC2", + MetricName: "CPUUtilization", + Dimensions: map[string][]string{ + "LoadBalancer": {"lb1", "lb2", "lb3"}, + "InstanceId": {"i-123", "*", "i-789"}, + }, + Period: 300, + Expression: "", + MatchExact: matchExact, + Statistic: "Average", + MetricQueryType: models.MetricQueryTypeSearch, + MetricEditorMode: models.MetricEditorModeBuilder, + } + + mdq, err := executor.buildMetricDataQuery(contextWithFeaturesEnabled(features.FlagCloudWatchNewLabelParsing), query) + require.NoError(t, err) + assert.Equal(t, `REMOVE_EMPTY(SEARCH('{"AWS/EC2","InstanceId","LoadBalancer"} MetricName="CPUUtilization" "LoadBalancer"=("lb1" OR "lb2" OR "lb3")', 'Average', 300))`, *mdq.Expression) + assert.Equal(t, "${LABEL}|&|${PROP('Dim.InstanceId')}|&|${PROP('Dim.LoadBalancer')}", *mdq.Label) + }) + + t.Run("Query has multiple dimensions and an account Id", func(t *testing.T) { + query := &models.CloudWatchQuery{ + Namespace: "AWS/EC2", + MetricName: "CPUUtilization", + Dimensions: map[string][]string{ + "LoadBalancer": {"lb1", "lb2", "lb3"}, + "InstanceId": {"i-123", "*", "i-789"}, + }, + Period: 300, + Expression: "", + MatchExact: matchExact, + AccountId: aws.String("some account id"), + Statistic: "Average", + MetricQueryType: models.MetricQueryTypeSearch, + MetricEditorMode: models.MetricEditorModeBuilder, + } + + mdq, err := executor.buildMetricDataQuery(contextWithFeaturesEnabled(features.FlagCloudWatchNewLabelParsing), query) + require.NoError(t, err) + assert.Equal(t, `REMOVE_EMPTY(SEARCH('{"AWS/EC2","InstanceId","LoadBalancer"} MetricName="CPUUtilization" "LoadBalancer"=("lb1" OR "lb2" OR "lb3") :aws.AccountId="some account id"', 'Average', 300))`, *mdq.Expression) + assert.Equal(t, "${LABEL}|&|${PROP('Dim.InstanceId')}|&|${PROP('Dim.LoadBalancer')}", *mdq.Label) + }) + t.Run("Query has a dimension key with a space", func(t *testing.T) { query := &models.CloudWatchQuery{ Namespace: "AWS/Kafka", @@ -465,6 +510,74 @@ func TestMetricDataQueryBuilder(t *testing.T) { assert.Equal(t, `REMOVE_EMPTY(SEARCH('Namespace="AWS/EC2" MetricName="CPUUtilization" "LoadBalancer"="lb1" "InstanceId"', 'Average', 300))`, *mdq.Expression) assert.Equal(t, "LB: ${PROP('Dim.LoadBalancer')|&|${PROP('Dim.InstanceId')}", *mdq.Label) }) + + t.Run("query has multiple dimensions and an account Id", func(t *testing.T) { + query := &models.CloudWatchQuery{ + Namespace: "AWS/EC2", + MetricName: "CPUUtilization", + Dimensions: map[string][]string{ + "LoadBalancer": {"lb1", "lb2", "lb3"}, + "InstanceId": {"i-123", "*", "i-789"}, + }, + Period: 300, + Expression: "", + MatchExact: matchExact, + Statistic: "Average", + MetricQueryType: models.MetricQueryTypeSearch, + MetricEditorMode: models.MetricEditorModeBuilder, + } + + mdq, err := executor.buildMetricDataQuery(contextWithFeaturesEnabled(features.FlagCloudWatchNewLabelParsing), query) + require.NoError(t, err) + assert.Equal(t, `REMOVE_EMPTY(SEARCH('Namespace="AWS/EC2" MetricName="CPUUtilization" "LoadBalancer"=("lb1" OR "lb2" OR "lb3") "InstanceId"', 'Average', 300))`, *mdq.Expression) + assert.Equal(t, "${LABEL}|&|${PROP('Dim.InstanceId')}|&|${PROP('Dim.LoadBalancer')}", *mdq.Label) + }) + + t.Run("query has multiple dimensions and an account Id", func(t *testing.T) { + query := &models.CloudWatchQuery{ + Namespace: "AWS/EC2", + MetricName: "CPUUtilization", + Dimensions: map[string][]string{ + "LoadBalancer": {"lb1", "lb2", "lb3"}, + "InstanceId": {"i-123", "*", "i-789"}, + }, + Period: 300, + Expression: "", + MatchExact: matchExact, + AccountId: aws.String("some account id"), + Statistic: "Average", + MetricQueryType: models.MetricQueryTypeSearch, + MetricEditorMode: models.MetricEditorModeBuilder, + } + + mdq, err := executor.buildMetricDataQuery(contextWithFeaturesEnabled(features.FlagCloudWatchNewLabelParsing), query) + require.NoError(t, err) + assert.Equal(t, `REMOVE_EMPTY(SEARCH('Namespace="AWS/EC2" MetricName="CPUUtilization" "LoadBalancer"=("lb1" OR "lb2" OR "lb3") "InstanceId" :aws.AccountId="some account id"', 'Average', 300))`, *mdq.Expression) + assert.Equal(t, "${LABEL}|&|${PROP('Dim.InstanceId')}|&|${PROP('Dim.LoadBalancer')}", *mdq.Label) + }) + + t.Run("Query has a custom label", func(t *testing.T) { + query := &models.CloudWatchQuery{ + Namespace: "AWS/EC2", + MetricName: "CPUUtilization", + Dimensions: map[string][]string{ + "LoadBalancer": {"lb1"}, + "InstanceId": {"i-123", "*", "i-789"}, + }, + Period: 300, + Expression: "", + MatchExact: matchExact, + Statistic: "Average", + Label: "LB: ${PROP('Dim.LoadBalancer')", + MetricQueryType: models.MetricQueryTypeSearch, + MetricEditorMode: models.MetricEditorModeBuilder, + } + + mdq, err := executor.buildMetricDataQuery(contextWithFeaturesEnabled(features.FlagCloudWatchNewLabelParsing), query) + require.NoError(t, err) + assert.Equal(t, `REMOVE_EMPTY(SEARCH('Namespace="AWS/EC2" MetricName="CPUUtilization" "LoadBalancer"="lb1" "InstanceId"', 'Average', 300))`, *mdq.Expression) + assert.Equal(t, "LB: ${PROP('Dim.LoadBalancer')|&|${PROP('Dim.InstanceId')}", *mdq.Label) + }) }) t.Run("Query has invalid characters in dimension values", func(t *testing.T) { diff --git a/pkg/tsdb/cloudwatch/models/api.go b/pkg/tsdb/cloudwatch/models/api.go index c54c156b12397..0a701bd94e402 100644 --- a/pkg/tsdb/cloudwatch/models/api.go +++ b/pkg/tsdb/cloudwatch/models/api.go @@ -71,3 +71,20 @@ type EC2APIProvider interface { DescribeRegionsWithContext(ctx context.Context, in *ec2.DescribeRegionsInput, opts ...request.Option) (*ec2.DescribeRegionsOutput, error) DescribeInstancesPagesWithContext(ctx context.Context, in *ec2.DescribeInstancesInput, fn func(*ec2.DescribeInstancesOutput, bool) bool, opts ...request.Option) error } + +type CloudWatchLogsAPIProvider interface { + DescribeLogGroups(*cloudwatchlogs.DescribeLogGroupsInput) (*cloudwatchlogs.DescribeLogGroupsOutput, error) +} + +type OAMClientProvider interface { + ListSinks(*oam.ListSinksInput) (*oam.ListSinksOutput, error) + ListAttachedLinks(*oam.ListAttachedLinksInput) (*oam.ListAttachedLinksOutput, error) +} + +type LogGroupsProvider interface { + GetLogGroups(request resources.LogGroupsRequest) ([]resources.ResourceResponse[resources.LogGroup], error) +} + +type AccountsProvider interface { + GetAccountsForCurrentUserOrRole() ([]resources.ResourceResponse[resources.Account], error) +} diff --git a/pkg/tsdb/cloudwatch/services/logs.go b/pkg/tsdb/cloudwatch/services/logs.go new file mode 100644 index 0000000000000..64658bc51df0e --- /dev/null +++ b/pkg/tsdb/cloudwatch/services/logs.go @@ -0,0 +1,53 @@ +package services + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloudwatchlogs" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils" +) + +type LogGroupsService struct { + logGroupsAPI models.CloudWatchLogsAPIProvider + isCrossAccountEnabled bool +} + +func NewLogGroupsService(logsClient models.CloudWatchLogsAPIProvider, isCrossAccountEnabled bool) models.LogGroupsProvider { + return &LogGroupsService{logGroupsAPI: logsClient, isCrossAccountEnabled: isCrossAccountEnabled} +} + +func (s *LogGroupsService) GetLogGroups(req resources.LogGroupsRequest) ([]resources.ResourceResponse[resources.LogGroup], error) { + input := &cloudwatchlogs.DescribeLogGroupsInput{ + Limit: aws.Int64(req.Limit), + LogGroupNamePrefix: req.LogGroupNamePrefix, + } + + if s.isCrossAccountEnabled && req.AccountId != nil { + input.IncludeLinkedAccounts = aws.Bool(true) + if req.LogGroupNamePattern != nil { + input.LogGroupNamePrefix = req.LogGroupNamePattern + } + if !req.IsTargetingAllAccounts() { + // TODO: accept more than one account id in search + input.AccountIdentifiers = []*string{req.AccountId} + } + } + response, err := s.logGroupsAPI.DescribeLogGroups(input) + if err != nil || response == nil { + return nil, err + } + + var result []resources.ResourceResponse[resources.LogGroup] + for _, logGroup := range response.LogGroups { + result = append(result, resources.ResourceResponse[resources.LogGroup]{ + Value: resources.LogGroup{ + Arn: *logGroup.Arn, + Name: *logGroup.LogGroupName, + }, + AccountId: utils.Pointer(getAccountId(*logGroup.Arn)), + }) + } + + return result, nil +} diff --git a/pkg/tsdb/cloudwatch/services/logs_test.go b/pkg/tsdb/cloudwatch/services/logs_test.go new file mode 100644 index 0000000000000..a1b81a8d094eb --- /dev/null +++ b/pkg/tsdb/cloudwatch/services/logs_test.go @@ -0,0 +1,200 @@ +package services + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/cloudwatchlogs" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func Test_GetLogGroups(t *testing.T) { + t.Run("Should map log groups response", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return( + &cloudwatchlogs.DescribeLogGroupsOutput{ + LogGroups: []*cloudwatchlogs.LogGroup{ + {Arn: utils.Pointer("arn:aws:logs:us-east-1:111:log-group:group_a"), LogGroupName: utils.Pointer("group_a")}, + {Arn: utils.Pointer("arn:aws:logs:us-east-1:222:log-group:group_b"), LogGroupName: utils.Pointer("group_b")}, + {Arn: utils.Pointer("arn:aws:logs:us-east-1:333:log-group:group_c"), LogGroupName: utils.Pointer("group_c")}, + }, + }, nil) + service := NewLogGroupsService(mockLogsAPI, false) + + resp, err := service.GetLogGroups(resources.LogGroupsRequest{}) + + assert.NoError(t, err) + assert.Equal(t, []resources.ResourceResponse[resources.LogGroup]{ + { + AccountId: utils.Pointer("111"), + Value: resources.LogGroup{Arn: "arn:aws:logs:us-east-1:111:log-group:group_a", Name: "group_a"}, + }, + { + AccountId: utils.Pointer("222"), + Value: resources.LogGroup{Arn: "arn:aws:logs:us-east-1:222:log-group:group_b", Name: "group_b"}, + }, + { + AccountId: utils.Pointer("333"), + Value: resources.LogGroup{Arn: "arn:aws:logs:us-east-1:333:log-group:group_c", Name: "group_c"}, + }, + }, resp) + }) + + t.Run("Should only use LogGroupNamePrefix even if LogGroupNamePattern passed in resource call", func(t *testing.T) { + // TODO: use LogGroupNamePattern when we have accounted for its behavior, still a little unexpected at the moment + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) + service := NewLogGroupsService(mockLogsAPI, false) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{ + Limit: 0, + LogGroupNamePrefix: utils.Pointer("test"), + }) + + assert.NoError(t, err) + mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ + Limit: utils.Pointer(int64(0)), + LogGroupNamePrefix: utils.Pointer("test"), + }) + }) + + t.Run("Should call api without LogGroupNamePrefix nor LogGroupNamePattern if not passed in resource call", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) + service := NewLogGroupsService(mockLogsAPI, false) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{}) + + assert.NoError(t, err) + mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ + Limit: utils.Pointer(int64(0)), + }) + }) + + t.Run("Should return an error when API returns error", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, + fmt.Errorf("some error")) + service := NewLogGroupsService(mockLogsAPI, false) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{}) + + assert.Error(t, err) + assert.Equal(t, "some error", err.Error()) + }) +} + +func Test_GetLogGroups_crossAccountQuerying(t *testing.T) { + t.Run("Should not includeLinkedAccounts or accountId if isCrossAccountEnabled is set to false", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) + service := NewLogGroupsService(mockLogsAPI, false) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{ + ResourceRequest: resources.ResourceRequest{AccountId: utils.Pointer("accountId")}, + LogGroupNamePrefix: utils.Pointer("prefix"), + }) + + assert.NoError(t, err) + mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ + Limit: utils.Pointer(int64(0)), + LogGroupNamePrefix: utils.Pointer("prefix"), + }) + }) + + t.Run("Should replace LogGroupNamePrefix if LogGroupNamePattern passed in resource call", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) + service := NewLogGroupsService(mockLogsAPI, true) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{ + ResourceRequest: resources.ResourceRequest{AccountId: utils.Pointer("accountId")}, + LogGroupNamePrefix: utils.Pointer("prefix"), + LogGroupNamePattern: utils.Pointer("pattern"), + }) + + assert.NoError(t, err) + mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ + AccountIdentifiers: []*string{utils.Pointer("accountId")}, + Limit: utils.Pointer(int64(0)), + LogGroupNamePrefix: utils.Pointer("pattern"), + IncludeLinkedAccounts: utils.Pointer(true), + }) + }) + + t.Run("Should includeLinkedAccounts,and accountId if isCrossAccountEnabled is set to true", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) + service := NewLogGroupsService(mockLogsAPI, true) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{ + ResourceRequest: resources.ResourceRequest{AccountId: utils.Pointer("accountId")}, + }) + + assert.NoError(t, err) + mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ + Limit: utils.Pointer(int64(0)), + IncludeLinkedAccounts: utils.Pointer(true), + AccountIdentifiers: []*string{utils.Pointer("accountId")}, + }) + }) + + t.Run("Should should not override prefix is there is no logGroupNamePattern", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) + service := NewLogGroupsService(mockLogsAPI, true) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{ + ResourceRequest: resources.ResourceRequest{AccountId: utils.Pointer("accountId")}, + LogGroupNamePrefix: utils.Pointer("prefix"), + }) + assert.NoError(t, err) + mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ + AccountIdentifiers: []*string{utils.Pointer("accountId")}, + Limit: utils.Pointer(int64(0)), + LogGroupNamePrefix: utils.Pointer("prefix"), + IncludeLinkedAccounts: utils.Pointer(true), + }) + }) + + t.Run("Should not includeLinkedAccounts, or accountId if accountId is nil", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) + service := NewLogGroupsService(mockLogsAPI, true) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{ + LogGroupNamePrefix: utils.Pointer("prefix"), + }) + + assert.NoError(t, err) + mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ + Limit: utils.Pointer(int64(0)), + LogGroupNamePrefix: utils.Pointer("prefix"), + }) + }) + + t.Run("Should should not override prefix is there is no logGroupNamePattern", func(t *testing.T) { + mockLogsAPI := &mocks.LogsAPI{} + mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) + service := NewLogGroupsService(mockLogsAPI, true) + + _, err := service.GetLogGroups(resources.LogGroupsRequest{ + ResourceRequest: resources.ResourceRequest{ + AccountId: utils.Pointer("accountId"), + }, + LogGroupNamePrefix: utils.Pointer("prefix"), + }) + + assert.NoError(t, err) + mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ + AccountIdentifiers: []*string{utils.Pointer("accountId")}, + IncludeLinkedAccounts: utils.Pointer(true), + Limit: utils.Pointer(int64(0)), + LogGroupNamePrefix: utils.Pointer("prefix"), + }) + }) +} diff --git a/public/app/plugins/datasource/cloudwatch/Search.tsx b/public/app/plugins/datasource/cloudwatch/Search.tsx new file mode 100644 index 0000000000000..e7af681ffe120 --- /dev/null +++ b/public/app/plugins/datasource/cloudwatch/Search.tsx @@ -0,0 +1,39 @@ +import { debounce } from 'lodash'; +import React, { useEffect, useMemo, useState } from 'react'; + +import { Icon, Input, useStyles2 } from '@grafana/ui'; + +import getStyles from './components/styles'; + +// TODO: consider moving search into grafana/ui, this is mostly the same as that in azure monitor +const Search = ({ searchFn, searchPhrase }: { searchPhrase: string; searchFn: (searchPhrase: string) => void }) => { + const [searchFilter, setSearchFilter] = useState(searchPhrase); + const styles = useStyles2(getStyles); + + const debouncedSearch = useMemo(() => debounce(searchFn, 600), [searchFn]); + + useEffect(() => { + return () => { + // Stop the invocation of the debounced function after unmounting + debouncedSearch?.cancel(); + }; + }, [debouncedSearch]); + + return ( + } + value={searchFilter} + onChange={(event) => { + const searchPhrase = event.currentTarget.value; + setSearchFilter(searchPhrase); + debouncedSearch(searchPhrase); + }} + placeholder="search by log group name prefix" + /> + ); +}; + +export default Search; diff --git a/public/app/plugins/datasource/cloudwatch/components/Account.test.tsx b/public/app/plugins/datasource/cloudwatch/components/Account.test.tsx new file mode 100644 index 0000000000000..e2803524fd1ac --- /dev/null +++ b/public/app/plugins/datasource/cloudwatch/components/Account.test.tsx @@ -0,0 +1,65 @@ +import { render, screen } from '@testing-library/react'; +import React from 'react'; +import selectEvent from 'react-select-event'; + +import { Account } from './Account'; + +export const AccountOptions = [ + { + value: '123456789', + label: 'test-account1', + description: '123456789', + }, + { + value: '432156789013', + label: 'test-account2', + description: '432156789013', + }, + { + value: '999999999999', + label: 'test-account3', + description: '999999999999', + }, + { + label: 'Template Variables', + options: [ + { + value: '$fakeVar', + label: '$fakeVar', + }, + ], + }, +]; +describe('Account', () => { + const props = { + accountOptions: AccountOptions, + region: 'us-east-2', + onChange: jest.fn(), + accountId: '123456789012', + }; + + it('should not render if there are no accounts', async () => { + render(); + expect(screen.queryByLabelText('Account Selection')).not.toBeInTheDocument(); + }); + + it('should render a selectable field of accounts if there are accounts', async () => { + const onChange = jest.fn(); + render(); + expect(screen.getByLabelText('Account Selection')).toBeInTheDocument(); + await selectEvent.select(screen.getByLabelText('Account Selection'), 'test-account3', { container: document.body }); + expect(onChange).toBeCalledWith('999999999999'); + }); + + it("should default to 'all' if there is no selection", () => { + render(); + expect(screen.getByLabelText('Account Selection')).toBeInTheDocument(); + expect(screen.getByText('All')).toBeInTheDocument(); + }); + + it('should select an uninterpolated template variable if it has been selected', () => { + render(); + expect(screen.getByLabelText('Account Selection')).toBeInTheDocument(); + expect(screen.getByText('$fakeVar')).toBeInTheDocument(); + }); +}); diff --git a/public/app/plugins/datasource/cloudwatch/components/Account.tsx b/public/app/plugins/datasource/cloudwatch/components/Account.tsx new file mode 100644 index 0000000000000..57cde6ac83aa8 --- /dev/null +++ b/public/app/plugins/datasource/cloudwatch/components/Account.tsx @@ -0,0 +1,54 @@ +import React, { useMemo } from 'react'; + +import { SelectableValue } from '@grafana/data'; +import { EditorField } from '@grafana/experimental'; +import { Select } from '@grafana/ui'; + +export interface Props { + onChange: (accountId?: string) => void; + accountOptions: Array>; + accountId?: string; +} + +export const ALL_ACCOUNTS_OPTION = { + label: 'All', + value: 'all', + description: 'Target all linked accounts', +}; + +export function Account({ accountId, onChange, accountOptions }: Props) { + const selectedAccountExistsInOptions = useMemo( + () => + accountOptions.find((a) => { + if (a.options) { + const matchingTemplateVar = a.options.find((tempVar: SelectableValue) => { + return tempVar.value === accountId; + }); + return matchingTemplateVar; + } + return a.value === accountId; + }), + [accountOptions, accountId] + ); + + if (accountOptions.length === 0) { + return null; + } + + return ( + + + + {Component && } + + ); +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Row.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Row.tsx new file mode 100644 index 0000000000000..5233e76718f1a --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Row.tsx @@ -0,0 +1,27 @@ +import React, { ReactNode } from 'react'; +import { InlineFieldRow, stylesFactory, useTheme } from '@grafana/ui'; +import { GrafanaTheme } from '@grafana/data'; +import { css, cx } from '@emotion/css'; + +interface Props { + children: ReactNode | ReactNode[]; +} + +export const Row = (props: Props) => { + const theme = useTheme(); + const styles = getStyles(theme); + return {props.children}; +}; + +const getStyles = stylesFactory((theme: GrafanaTheme) => { + return { + row: css` + width: 100%; + padding-bottom: 5px; + & > & { + border-left: 1px solid ${theme.colors.border2}; + padding: 5px 0 5px 10px; + } + `, + }; +}); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Select.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Select.tsx new file mode 100644 index 0000000000000..692f64092a6cc --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Select.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { InlineField, Select as SelectField } from '@grafana/ui'; +import { SelectableValue } from '@grafana/data'; +import { QueryBuilderFieldProps } from './types'; +import { onBuilderChange } from '.'; + +interface Props extends QueryBuilderFieldProps { + entries: Record; +} + +export const Select = (props: Props) => { + const onChange = (option: SelectableValue) => { + if (null !== option) { + onBuilderChange(props, option.value); + } + }; + const entries = Object.entries(props.entries).map((entry) => { + return { value: entry[0], label: String(entry[1]) }; + }); + const hasCustomValue = entries.filter((entry) => entry.value === props.options.builder).length === 0; + if (hasCustomValue) { + entries.push({ value: props.options.builder, label: props.options.builder }); + } + return ( + + { + onChange({ value: v, label: v }); + }} + allowCustomValue + isClearable + /> + + ); +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Table.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Table.tsx new file mode 100644 index 0000000000000..0863613024673 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Table.tsx @@ -0,0 +1,88 @@ +import React from 'react'; +import { InlineField } from '@grafana/ui'; +import { QueryBuilderFieldProps } from './types'; +import { onBuilderChange } from '.'; +import uniqueId from 'lodash/uniqueId'; +import AceEditor from 'react-ace'; +import 'ace-builds/src-noconflict/mode-javascript'; +import 'ace-builds/src-noconflict/mode-hjson'; +import 'ace-builds/src-noconflict/mode-sql'; +import 'ace-builds/src-noconflict/theme-terminal'; + +interface Props extends QueryBuilderFieldProps { + namesFieldName: string; + typesFieldName: string; + rowsFieldName: string; +} + +const encodeInline = (names: string[], types: string[], rows: string[][]): string => { + let inline = ''; + if (undefined !== names && names.length > 0) { + for (let i in names) { + inline += names[i] + ':' + types[i] + ','; + } + inline = inline.slice(0, -1) + '\n'; + for (let row of rows) { + for (let col of row) { + inline += col + ','; + } + inline = inline.slice(0, -1) + '\n'; + } + } + return inline; +}; + +const decodeInline = (inline: string): [string[], string[], string[][]] => { + const lines = inline.split('\n'); + const header = lines[0]; + const fields = header.split(','); + let names = []; + let types = []; + let rows = []; + for (let field of fields) { + let name_type = field.split(':'); + if (name_type[0] !== '' && name_type[1] !== undefined) { + names.push(name_type[0]); + types.push(name_type[1]); + } + } + for (let line of lines.slice(1)) { + rows.push(line.split(',')); + } + return [names, types, rows]; +}; + +export const Table = (props: Props) => { + const onChange = (value: string) => { + const [names, types, rows] = decodeInline(value); + onBuilderChange(props, { columnNames: names, columnTypes: types, rows: rows }); + }; + return ( + + + + ); +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/index.ts new file mode 100644 index 0000000000000..2dd900a16ede2 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/index.ts @@ -0,0 +1,19 @@ +export { QueryBuilderComponentSelector } from './QueryBuilderComponentSelector'; +export { + useScopedQueryBuilderProps, + useScopedQueryBuilderFieldProps, + ScopeType, + onBuilderChange, + useQueryBuilderAutoSubmit, +} from './QueryBuilderComponent'; +export { Input } from './Input'; +export { Multiple } from './Multiple'; +export { Checkbox } from './Checkbox'; +export { Select } from './Select'; +export { MultiSelect } from './Multiselect'; +export { Code } from './Code'; +export { Table } from './Table'; +export { KeyValue } from './KeyValue'; +export { DateTime } from './DateTime'; +export { DateInterval } from './DateInterval'; +export { Row } from './Row'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/types.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/types.ts new file mode 100644 index 0000000000000..72d234c018919 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/types.ts @@ -0,0 +1,22 @@ +import { ComponentType } from 'react'; +import { QueryBuilderProps } from '../types'; + +export interface QueryBuilderFieldProps extends QueryBuilderProps { + name: string; + label: string | undefined; + description: string; + onChange?: (newBuilder: any) => void; +} + +export interface QueryComponent { + queryType: string; +} + +export interface Component { + type: string; +} + +export type QueryBuilderComponent = ComponentType & + Type & { + fields: string[]; + }; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Aggregation.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Aggregation.tsx new file mode 100644 index 0000000000000..0ad0f01eab20f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Aggregation.tsx @@ -0,0 +1,77 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; + +import { + Cardinality, + Count, + DoubleAny, + DoubleFirst, + DoubleLast, + DoubleMax, + DoubleMean, + DoubleMin, + DoubleSum, + Filtered, + FloatAny, + FloatFirst, + FloatLast, + FloatMax, + FloatMin, + FloatSum, + Histogram, + HyperUnique, + Javascript, + LongAny, + LongFirst, + LongLast, + LongMax, + LongMin, + LongSum, + QuantilesDoublesSketch, + StringAny, + StringFirstFolding, + StringFirst, + StringLastFolding, + StringLast, +} from './'; + +export const Aggregation = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Cardinality.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Cardinality.tsx new file mode 100644 index 0000000000000..125018c6cbd69 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Cardinality.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Multiple, Row } from '../abstract'; + +export const Cardinality = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Cardinality); + return ( + <> + + + + + + + + + + + + ); +}; +Cardinality.type = 'cardinality'; +Cardinality.fields = ['name', 'fields', 'byRow', 'round']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Count.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Count.tsx new file mode 100644 index 0000000000000..420b6bebb7886 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Count.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Count = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Count); + return ( + + + + ); +}; +Count.type = 'count'; +Count.fields = ['name']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleAny.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleAny.tsx new file mode 100644 index 0000000000000..a6978ae68ea5b --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleAny.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const DoubleAny = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleAny); + return ( + + + + + ); +}; +DoubleAny.type = 'doubleAny'; +DoubleAny.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleFirst.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleFirst.tsx new file mode 100644 index 0000000000000..f7e32e147a8fb --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleFirst.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const DoubleFirst = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleFirst); + return ( + + + + + ); +}; +DoubleFirst.type = 'doubleFirst'; +DoubleFirst.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleLast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleLast.tsx new file mode 100644 index 0000000000000..9fea786ce7ae6 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleLast.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const DoubleLast = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleLast); + return ( + + + + + ); +}; +DoubleLast.type = 'doubleLast'; +DoubleLast.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMax.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMax.tsx new file mode 100644 index 0000000000000..a18ccd11d5685 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMax.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const DoubleMax = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleMax); + return ( + + + + + + ); +}; +DoubleMax.type = 'doubleMax'; +DoubleMax.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMean.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMean.tsx new file mode 100644 index 0000000000000..64a98cb3fce53 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMean.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const DoubleMean = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleMean); + return ( + + + + + ); +}; +DoubleMean.type = 'doubleMean'; +DoubleMean.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMin.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMin.tsx new file mode 100644 index 0000000000000..3de9fc513bfc1 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMin.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const DoubleMin = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleMin); + return ( + + + + + + ); +}; +DoubleMin.type = 'doubleMin'; +DoubleMin.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleSum.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleSum.tsx new file mode 100644 index 0000000000000..ee1c1b6bc1963 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleSum.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const DoubleSum = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleSum); + return ( + + + + + + ); +}; +DoubleSum.type = 'doubleSum'; +DoubleSum.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Filtered.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Filtered.tsx new file mode 100644 index 0000000000000..3bd649446112f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Filtered.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { Aggregation } from './'; +import { Filter } from '../filter'; + +export const Filtered = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Filtered); + return ( + + + + + + ); +}; +Filtered.type = 'filtered'; +Filtered.fields = ['name', 'filter', 'aggregator']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatAny.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatAny.tsx new file mode 100644 index 0000000000000..499d99f836c17 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatAny.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const FloatAny = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FloatAny); + return ( + + + + + ); +}; +FloatAny.type = 'floatAny'; +FloatAny.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatFirst.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatFirst.tsx new file mode 100644 index 0000000000000..86da2ae9e01c3 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatFirst.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const FloatFirst = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FloatFirst); + return ( + + + + + ); +}; +FloatFirst.type = 'floatFirst'; +FloatFirst.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatLast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatLast.tsx new file mode 100644 index 0000000000000..31161c94bb5ff --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatLast.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const FloatLast = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FloatLast); + return ( + + + + + ); +}; +FloatLast.type = 'floatLast'; +FloatLast.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMax.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMax.tsx new file mode 100644 index 0000000000000..9454cbc003ace --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMax.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const FloatMax = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FloatMax); + return ( + + + + + + ); +}; +FloatMax.type = 'floatMax'; +FloatMax.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMin.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMin.tsx new file mode 100644 index 0000000000000..3b425cfd3ff10 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMin.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const FloatMin = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FloatMin); + return ( + + + + + + ); +}; +FloatMin.type = 'floatMin'; +FloatMin.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatSum.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatSum.tsx new file mode 100644 index 0000000000000..d7e111992d680 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatSum.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const FloatSum = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FloatSum); + return ( + + + + + + ); +}; +FloatSum.type = 'floatSum'; +FloatSum.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Histogram.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Histogram.tsx new file mode 100644 index 0000000000000..b2e8cc605d90b --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Histogram.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; + +export const Histogram = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Histogram); + return ( + + + + + + ); +}; +Histogram.type = 'histogram'; +Histogram.fields = ['name', 'fieldName', 'breaks']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/HyperUnique.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/HyperUnique.tsx new file mode 100644 index 0000000000000..b1661a57503f3 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/HyperUnique.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; + +export const HyperUnique = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, HyperUnique); + return ( + + + + + + ); +}; +HyperUnique.type = 'hyperUnique'; +HyperUnique.fields = ['name', 'fieldName', 'round']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Javascript.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Javascript.tsx new file mode 100644 index 0000000000000..45aecca05e79f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Javascript.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Code, Row } from '../abstract'; + +export const Javascript = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Javascript); + return ( + + + + + + + + ); +}; +Javascript.type = 'javascript'; +Javascript.fields = ['name', 'fieldNames', 'fnAggregate', 'fnCombine', 'fnReset']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongAny.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongAny.tsx new file mode 100644 index 0000000000000..e02fa0b16d4bb --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongAny.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const LongAny = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LongAny); + return ( + + + + + ); +}; +LongAny.type = 'longAny'; +LongAny.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongFirst.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongFirst.tsx new file mode 100644 index 0000000000000..32fbfacc37d55 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongFirst.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const LongFirst = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LongFirst); + return ( + + + + + ); +}; +LongFirst.type = 'longFirst'; +LongFirst.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongLast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongLast.tsx new file mode 100644 index 0000000000000..9cda992b8e59e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongLast.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const LongLast = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LongLast); + return ( + + + + + ); +}; +LongLast.type = 'count'; +LongLast.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMax.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMax.tsx new file mode 100644 index 0000000000000..e227875d161d5 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMax.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const LongMax = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LongMax); + return ( + + + + + + ); +}; +LongMax.type = 'longMax'; +LongMax.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMin.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMin.tsx new file mode 100644 index 0000000000000..13261d739369f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMin.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const LongMin = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LongMin); + return ( + + + + + + ); +}; +LongMin.type = 'longMin'; +LongMin.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongSum.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongSum.tsx new file mode 100644 index 0000000000000..6523543563810 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongSum.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const LongSum = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LongSum); + return ( + + + + + + ); +}; +LongSum.type = 'longSum'; +LongSum.fields = ['name', 'fieldName', 'expression']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/QuantilesDoublesSketch.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/QuantilesDoublesSketch.tsx new file mode 100644 index 0000000000000..ee5ee8657aa5a --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/QuantilesDoublesSketch.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const QuantilesDoublesSketch = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, QuantilesDoublesSketch); + return ( + + + + + + ); +}; +QuantilesDoublesSketch.type = 'quantilesDoublesSketch'; +QuantilesDoublesSketch.fields = ['name', 'fieldName', 'k']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringAny.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringAny.tsx new file mode 100644 index 0000000000000..4c1a7ebb56e8e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringAny.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const StringAny = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, StringAny); + return ( + + + + + + ); +}; +StringAny.type = 'stringAny'; +StringAny.fields = ['name', 'fieldName', 'maxStringBytes']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirst.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirst.tsx new file mode 100644 index 0000000000000..29d15fcaa348e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirst.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const StringFirst = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, StringFirst); + return ( + + + + + + ); +}; +StringFirst.type = 'stringFirst'; +StringFirst.fields = ['name', 'fieldName', 'maxStringBytes']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirstFolding.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirstFolding.tsx new file mode 100644 index 0000000000000..06fa49df3d65b --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirstFolding.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const StringFirstFolding = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, StringFirstFolding); + return ( + + + + + + ); +}; +StringFirstFolding.type = 'stringFirstFolding'; +StringFirstFolding.fields = ['name', 'fieldName', 'maxStringBytes']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLast.tsx new file mode 100644 index 0000000000000..67313deed3ec5 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLast.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const StringLast = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, StringLast); + return ( + + + + + + ); +}; +StringLast.type = 'stringLast'; +StringLast.fields = ['name', 'fieldName', 'maxStringBytes']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLastFolding.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLastFolding.tsx new file mode 100644 index 0000000000000..6133e4f9c9a4d --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLastFolding.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const StringLastFolding = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, StringLastFolding); + return ( + + + + + + ); +}; +StringLastFolding.type = 'stringLastFolding'; +StringLastFolding.fields = ['name', 'fieldName', 'maxStringBytes']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/index.ts new file mode 100644 index 0000000000000..e5d50ab65aefa --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/index.ts @@ -0,0 +1,32 @@ +export { Aggregation } from './Aggregation'; +export { Cardinality } from './Cardinality'; +export { Count } from './Count'; +export { DoubleAny } from './DoubleAny'; +export { DoubleFirst } from './DoubleFirst'; +export { DoubleLast } from './DoubleLast'; +export { DoubleMax } from './DoubleMax'; +export { DoubleMean } from './DoubleMean'; +export { DoubleMin } from './DoubleMin'; +export { DoubleSum } from './DoubleSum'; +export { Filtered } from './Filtered'; +export { FloatAny } from './FloatAny'; +export { FloatFirst } from './FloatFirst'; +export { FloatLast } from './FloatLast'; +export { FloatMax } from './FloatMax'; +export { FloatMin } from './FloatMin'; +export { FloatSum } from './FloatSum'; +export { Histogram } from './Histogram'; +export { HyperUnique } from './HyperUnique'; +export { Javascript } from './Javascript'; +export { LongAny } from './LongAny'; +export { LongFirst } from './LongFirst'; +export { LongLast } from './LongLast'; +export { LongMax } from './LongMax'; +export { LongMin } from './LongMin'; +export { LongSum } from './LongSum'; +export { QuantilesDoublesSketch } from './QuantilesDoublesSketch'; +export { StringAny } from './StringAny'; +export { StringFirstFolding } from './StringFirstFolding'; +export { StringFirst } from './StringFirst'; +export { StringLastFolding } from './StringLastFolding'; +export { StringLast } from './StringLast'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Bound.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Bound.tsx new file mode 100644 index 0000000000000..5c696329b6813 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Bound.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { Polygon, Radius, Rectangular } from './'; + +export const Bound = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Polygon.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Polygon.tsx new file mode 100644 index 0000000000000..e3db137290f84 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Polygon.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Polygon = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Polygon); + return ( + + + + + ); +}; +Polygon.type = 'polygon'; +Polygon.fields = ['abscissa', 'ordinate']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Radius.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Radius.tsx new file mode 100644 index 0000000000000..77875ed934dba --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Radius.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; + +export const Radius = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Radius); + return ( + <> + + + + + + + + ); +}; +Radius.type = 'radius'; +Radius.fields = ['coords', 'radius']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Rectangular.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Rectangular.tsx new file mode 100644 index 0000000000000..66a88e6ed1cdd --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Rectangular.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; + +export const Rectangular = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Rectangular); + return ( + <> + + + + + + + + ); +}; +Rectangular.type = 'rectangular'; +Rectangular.fields = ['minCoords', 'maxCoords']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/index.ts new file mode 100644 index 0000000000000..231023d82e0ef --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/index.ts @@ -0,0 +1,4 @@ +export { Bound } from './Bound'; +export { Polygon } from './Polygon'; +export { Radius } from './Radius'; +export { Rectangular } from './Rectangular'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/DataSource.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/DataSource.tsx new file mode 100644 index 0000000000000..3dd33257c686d --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/DataSource.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { GlobalTable, Inline, Join, Lookup, Query, Table, Union } from './'; + +export const DataSource = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/GlobalTable.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/GlobalTable.tsx new file mode 100644 index 0000000000000..e281527d945eb --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/GlobalTable.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const GlobalTable = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, GlobalTable); + return ( + + + + ); +}; +GlobalTable.type = 'globalTable'; +GlobalTable.fields = ['name']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Inline.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Inline.tsx new file mode 100644 index 0000000000000..43a3324c71c95 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Inline.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Table, Row } from '../abstract'; + +export const Inline = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Inline); + return ( + + + + ); +}; +Inline.type = 'inline'; +Inline.fields = ['columnNames', 'columnTypes', 'rows']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Join.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Join.tsx new file mode 100644 index 0000000000000..3a2166c9ebf2b --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Join.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; +import { DataSource } from '.'; + +export const Join = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Join); + const scopedComponentProps = useScopedQueryBuilderProps(props, Join); + return ( + <> + + + + + + + + + + + + ); +}; +Lookup.type = 'lookup'; +Lookup.fields = ['lookup']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Query.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Query.tsx new file mode 100644 index 0000000000000..294b03fd79064 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Query.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, Row } from '../abstract'; +import { Query as QuerySelector } from '../query'; + +export const Query = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderProps(props, Query); + return ( + + + + ); +}; +Query.type = 'query'; +Query.fields = ['query']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Table.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Table.tsx new file mode 100644 index 0000000000000..73941280d3f75 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Table.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Table = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Table); + return ( + + + + ); +}; +Table.type = 'table'; +Table.fields = ['name']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Union.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Union.tsx new file mode 100644 index 0000000000000..c81483d54d818 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Union.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; + +export const Union = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Union); + return ( + + + + ); +}; +Union.type = 'union'; +Union.fields = ['dataSources']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/index.ts new file mode 100644 index 0000000000000..3cfa376037904 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/index.ts @@ -0,0 +1,8 @@ +export { DataSource } from './DataSource'; +export { GlobalTable } from './GlobalTable'; +export { Inline } from './Inline'; +export { Join } from './Join'; +export { Lookup } from './Lookup'; +export { Query } from './Query'; +export { Table } from './Table'; +export { Union } from './Union'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Default.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Default.tsx new file mode 100644 index 0000000000000..4820b352c6ca6 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Default.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; + +export const Default = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Default); + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; +Lookup.type = 'lookup'; +Lookup.fields = [ + 'dimension', + 'outputName', + 'name', + 'lookup', + 'retainMissingValue', + 'replaceMissingValueWith', + 'injective', + 'optimize', +]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/PrefixFiltered.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/PrefixFiltered.tsx new file mode 100644 index 0000000000000..ce3922b04d39e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/PrefixFiltered.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { Dimension } from '../dimension'; + +export const PrefixFiltered = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, PrefixFiltered); + return ( + <> + + + + + + + + ); +}; +PrefixFiltered.type = 'prefixFiltered'; +PrefixFiltered.fields = ['delegate', 'prefix']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegexFiltered.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegexFiltered.tsx new file mode 100644 index 0000000000000..88fa8bd103358 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegexFiltered.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { Dimension } from '../dimension'; + +export const RegexFiltered = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, RegexFiltered); + return ( + <> + + + + + + + + ); +}; +RegexFiltered.type = 'regexFiltered'; +RegexFiltered.fields = ['delegate', 'pattern']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegisteredLookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegisteredLookup.tsx new file mode 100644 index 0000000000000..34dbc347199cd --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegisteredLookup.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; + +export const RegisteredLookup = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, RegisteredLookup); + return ( + <> + + + + + + + + + + + + + + + + + + + ); +}; +RegisteredLookup.type = 'registeredLookup'; +RegisteredLookup.fields = [ + 'dimension', + 'outputName', + 'lookup', + 'retainMissingValue', + 'replaceMissingValueWith', + 'injective', + 'optimize', +]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/index.ts new file mode 100644 index 0000000000000..8c19466b61c5c --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/index.ts @@ -0,0 +1,8 @@ +export { Default } from './Default'; +export { Dimension } from './Dimension'; +export { Extraction } from './Extraction'; +export { ListFiltered } from './ListFiltered'; +export { Lookup } from './Lookup'; +export { RegisteredLookup } from './RegisteredLookup'; +export { PrefixFiltered } from './PrefixFiltered'; +export { RegexFiltered } from './RegexFiltered'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Bucket.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Bucket.tsx new file mode 100644 index 0000000000000..cfe13ee2f5b1c --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Bucket.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Bucket = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Bucket); + return ( + + + + + ); +}; +Bucket.type = 'bucket'; +Bucket.fields = ['size', 'offset']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Cascade.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Cascade.tsx new file mode 100644 index 0000000000000..8938e3e9be0a3 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Cascade.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { ExtractionFn } from './'; + +export const Cascade = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Cascade); + return ( + + + + ); +}; +Cascade.type = 'cascade'; +Cascade.fields = ['extractionFns']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/ExtractionFn.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/ExtractionFn.tsx new file mode 100644 index 0000000000000..802d132ee28f6 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/ExtractionFn.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { + Bucket, + Cascade, + Identity, + Javascript, + Lookup, + Lower, + Partial, + Regex, + RegisteredLookup, + SearchQuery, + StringFormat, + StrLen, + Substring, + TimeFormat, + Time, + Upper, +} from './'; + +export const ExtractionFn = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Identity.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Identity.tsx new file mode 100644 index 0000000000000..0f48e6507ed13 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Identity.tsx @@ -0,0 +1,27 @@ +import React, { useState } from 'react'; +import { InfoBox } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const Identity = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, Identity); + const [showInfo, setShowInfo] = useState(true); + return ( + <> + {showInfo && ( + + { + setShowInfo(false); + }} + > +

Identity. Whatever it does.

+
+
+ )} + + ); +}; +Identity.type = 'identity'; +Identity.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Javascript.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Javascript.tsx new file mode 100644 index 0000000000000..48f85bbc92891 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Javascript.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Code, Checkbox, Row } from '../abstract'; + +export const Javascript = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Javascript); + return ( + <> + + + + + + + + ); +}; +Javascript.type = 'javascript'; +Javascript.fields = ['function', 'injective']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lookup.tsx new file mode 100644 index 0000000000000..3e9f00150dbaf --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lookup.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { Map } from '../lookup'; + +export const Lookup = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Lookup); + return ( + <> + + + + + + + + + + + ); +}; +Lookup.type = 'lookup'; +Lookup.fields = ['lookup', 'retainMissingValue', 'replaceMissingValueWith', 'injective', 'optimize']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lower.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lower.tsx new file mode 100644 index 0000000000000..7ba9a76ea7109 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lower.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Lower = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Lower); + return ( + + + + ); +}; +Lower.type = 'lower'; +Lower.fields = ['locale']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Partial.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Partial.tsx new file mode 100644 index 0000000000000..637620dfa67de --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Partial.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Partial = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Partial); + return ( + + + + ); +}; +Partial.type = 'partial'; +Partial.fields = ['expr']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Regex.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Regex.tsx new file mode 100644 index 0000000000000..b3ba3b3b5ff50 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Regex.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; + +export const Regex = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Regex); + return ( + <> + + + + + + + + + + ); +}; +Regex.type = 'regex'; +Regex.fields = ['expr', 'index', 'replaceMissingValue', 'replaceMissingValueWith']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/RegisteredLookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/RegisteredLookup.tsx new file mode 100644 index 0000000000000..188fad052fa66 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/RegisteredLookup.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; + +export const RegisteredLookup = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, RegisteredLookup); + return ( + <> + + + + + + + + + + + + + ); +}; +RegisteredLookup.type = 'registeredLookup'; +RegisteredLookup.fields = ['lookup', 'retainMissingValue', 'replaceMissingValueWith', 'injective', 'optimize']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/SearchQuery.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/SearchQuery.tsx new file mode 100644 index 0000000000000..268f572069759 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/SearchQuery.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, Row } from '../abstract'; +import { SearchQuerySpec } from '../searchqueryspec'; + +export const SearchQuery = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderProps(props, SearchQuery); + return ( + + + + ); +}; +SearchQuery.type = 'searchQuery'; +SearchQuery.fields = ['query']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StrLen.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StrLen.tsx new file mode 100644 index 0000000000000..94e1dbe526c3f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StrLen.tsx @@ -0,0 +1,27 @@ +import React, { useState } from 'react'; +import { InfoBox } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const StrLen = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, StrLen); + const [showInfo, setShowInfo] = useState(true); + return ( + <> + {showInfo && ( + + { + setShowInfo(false); + }} + > +

Returns the length of dimension values (as if they were encoded in UTF-16)

+
+
+ )} + + ); +}; +StrLen.type = 'strlen'; +StrLen.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StringFormat.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StringFormat.tsx new file mode 100644 index 0000000000000..83954e2f12711 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StringFormat.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; + +export const StringFormat = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, StringFormat); + return ( + + + + + + ); +}; +Substring.type = 'substring'; +Substring.fields = ['index', 'length']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Time.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Time.tsx new file mode 100644 index 0000000000000..4f5e52fd31c74 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Time.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; + +export const Time = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Time); + return ( + <> + + + + + + + + + ); +}; +Time.type = 'time'; +Time.fields = ['timeFormat', 'resultFormat', 'joda']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/TimeFormat.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/TimeFormat.tsx new file mode 100644 index 0000000000000..715c5f67b0b25 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/TimeFormat.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { Granularity } from '../granularity'; + +export const TimeFormat = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, TimeFormat); + const scopedComponentProps = useScopedQueryBuilderProps(props, TimeFormat); + return ( + <> + + + + + + + + + + + + + ); +}; +TimeFormat.type = 'timeFormat'; +TimeFormat.fields = ['format', 'timeZone', 'locale', 'asMillis', 'granularity']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Upper.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Upper.tsx new file mode 100644 index 0000000000000..90f70b42459f2 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Upper.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Upper = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Upper); + return ( + + + + ); +}; +Upper.type = 'upper'; +Upper.fields = ['locale']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/index.ts new file mode 100644 index 0000000000000..a41778ca90843 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/index.ts @@ -0,0 +1,17 @@ +export { Bucket } from './Bucket'; +export { Cascade } from './Cascade'; +export { ExtractionFn } from './ExtractionFn'; +export { Identity } from './Identity'; +export { Javascript } from './Javascript'; +export { Lookup } from './Lookup'; +export { Lower } from './Lower'; +export { Partial } from './Partial'; +export { Regex } from './Regex'; +export { RegisteredLookup } from './RegisteredLookup'; +export { SearchQuery } from './SearchQuery'; +export { StringFormat } from './StringFormat'; +export { StrLen } from './StrLen'; +export { Substring } from './Substring'; +export { TimeFormat } from './TimeFormat'; +export { Time } from './Time'; +export { Upper } from './Upper'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/And.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/And.tsx new file mode 100644 index 0000000000000..39cdc0cb48faf --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/And.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { Filter } from './'; + +export const And = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, And); + return ( + + + + ); +}; +And.type = 'and'; +And.fields = ['fields']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Bound.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Bound.tsx new file mode 100644 index 0000000000000..e31dbbd02e125 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Bound.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Select, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; + +export const Bound = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Bound); + return ( + <> + + + + + + + + + + + + + + + + + + + ); +}; +Expression.type = 'expression'; +Expression.fields = ['expression', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Extraction.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Extraction.tsx new file mode 100644 index 0000000000000..cb6184856f7c1 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Extraction.tsx @@ -0,0 +1,39 @@ +import React, { useState } from 'react'; +import { InfoBox } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; + +export const Extraction = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Extraction); + const [showInfo, setShowInfo] = useState(true); + return ( + <> + {showInfo && ( + + { + setShowInfo(false); + }} + > +

+ The extraction filter is now deprecated. The selector filter with an extraction function specified + provides identical functionality and should be used instead. +

+
+
+ )} + + + + + + + + + ); +}; +Extraction.type = 'extraction'; +Extraction.fields = ['dimension', 'value', 'extractionFn']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/False.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/False.tsx new file mode 100644 index 0000000000000..48ac9821507fe --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/False.tsx @@ -0,0 +1,30 @@ +import React, { useState } from 'react'; +import { InfoBox } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const False = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, False); + const [showInfo, setShowInfo] = useState(true); + return ( + <> + {showInfo && ( + + { + setShowInfo(false); + }} + > +

+ The false filter is a filter which matches no value. It can be used to temporarily disable other filters + without removing the filter. +

+
+
+ )} + + ); +}; +False.type = 'false'; +False.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Filter.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Filter.tsx new file mode 100644 index 0000000000000..725f1d37c199e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Filter.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { + And, + Bound, + ColumnComparison, + Expression, + Extraction, + False, + Interval, + In, + Javascript, + Like, + Not, + Or, + Regex, + Search, + Selector, + Spatial, + True, +} from './'; + +export const Filter = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/FilterTuning.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/FilterTuning.tsx new file mode 100644 index 0000000000000..f6eac7e2e87dd --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/FilterTuning.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { InlineLabel } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; + +export const FilterTuning = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FilterTuning); + return ( + <> + + Filter tuning + + + + + + + + + + ); +}; +FilterTuning.type = 'filterTuning'; +FilterTuning.fields = ['minCardinalityToUseBitmapIndex', 'maxCardinalityToUseBitmapIndex', 'useBitmapIndex']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/In.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/In.tsx new file mode 100644 index 0000000000000..f7ab648bc75e3 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/In.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; + +export const In = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, In); + return ( + <> + + + + + + + + + + + + + + ); +}; +In.type = 'in'; +In.fields = ['dimension', 'values', 'extractionFn', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Interval.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Interval.tsx new file mode 100644 index 0000000000000..ff574eb4e2a59 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Interval.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, useScopedQueryBuilderProps, Input, Row } from '../abstract'; +import { Intervals } from '../querysegmentspec'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; + +export const Interval = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Interval); + const scopedComponentProps = useScopedQueryBuilderProps(props, Interval); + return ( + <> + + + + + + + + + + + + + + ); +}; +Interval.type = 'interval'; +Interval.fields = ['dimension', 'intervals', 'extractionFn', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Javascript.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Javascript.tsx new file mode 100644 index 0000000000000..1acf0ee883139 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Javascript.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Code, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; + +export const Javascript = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Javascript); + return ( + <> + + + + + + + + + + + + + + ); +}; +Javascript.type = 'javascript'; +Javascript.fields = ['dimension', 'function', 'extractionFn', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Like.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Like.tsx new file mode 100644 index 0000000000000..f4dd4f0d51f61 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Like.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; + +export const Like = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Like); + return ( + <> + + + + + + + + + + + + + ); +}; +Like.type = 'like'; +Like.fields = ['dimension', 'pattern', 'escape', 'extractionFn', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Not.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Not.tsx new file mode 100644 index 0000000000000..4bc28fe35e57a --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Not.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Row } from '../abstract'; +import { Filter } from './'; + +export const Not = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Not); + return ( + + + + ); +}; +Not.type = 'not'; +Not.fields = ['field']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Or.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Or.tsx new file mode 100644 index 0000000000000..af97580460445 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Or.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { Filter } from './'; + +export const Or = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Or); + return ( + <> + + + + + ); +}; +Or.type = 'or'; +Or.fields = ['fields']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Regex.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Regex.tsx new file mode 100644 index 0000000000000..173a0b7a97e1e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Regex.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; + +export const Regex = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Regex); + return ( + <> + + + + + + + + + + + + ); +}; +Regex.type = 'regex'; +Regex.fields = ['dimension', 'pattern', 'extractionFn', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Search.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Search.tsx new file mode 100644 index 0000000000000..cf7d202ffe53e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Search.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; +import { SearchQuerySpec } from '../searchqueryspec'; + +export const Search = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Search); + return ( + <> + + + + + + + + + + + + + + ); +}; +Search.type = 'search'; +Search.fields = ['dimension', 'query', 'extractionFn', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Selector.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Selector.tsx new file mode 100644 index 0000000000000..7e8cc25df7ab0 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Selector.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; + +export const Selector = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Selector); + return ( + <> + + + + + + + + + + + + ); +}; +Selector.type = 'selector'; +Selector.fields = ['dimension', 'value', 'extractionFn', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Spatial.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Spatial.tsx new file mode 100644 index 0000000000000..5795528898dcf --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Spatial.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { ExtractionFn } from '../extractionfn'; +import { FilterTuning } from '.'; +import { Bound } from '../bound'; + +export const Spatial = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Spatial); + return ( + <> + + + + + + + + + + + + + + ); +}; +Spatial.type = 'spatial'; +Spatial.fields = ['dimension', 'bound', 'extractionFn', 'filterTuning']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/True.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/True.tsx new file mode 100644 index 0000000000000..a8effcccf5a2d --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/True.tsx @@ -0,0 +1,30 @@ +import React, { useState } from 'react'; +import { InfoBox } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const True = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, True); + const [showInfo, setShowInfo] = useState(true); + return ( + <> + {showInfo && ( + + { + setShowInfo(false); + }} + > +

+ The true filter is a filter which matches all values. It can be used to temporarily disable other filters + without removing the filter. +

+
+
+ )} + + ); +}; +True.type = 'true'; +True.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/index.ts new file mode 100644 index 0000000000000..7a06f85aeeade --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/index.ts @@ -0,0 +1,19 @@ +export { And } from './And'; +export { Bound } from './Bound'; +export { ColumnComparison } from './ColumnComparison'; +export { Expression } from './Expression'; +export { Extraction } from './Extraction'; +export { False } from './False'; +export { Filter } from './Filter'; +export { FilterTuning } from './FilterTuning'; +export { Interval } from './Interval'; +export { In } from './In'; +export { Javascript } from './Javascript'; +export { Like } from './Like'; +export { Not } from './Not'; +export { Or } from './Or'; +export { Regex } from './Regex'; +export { Search } from './Search'; +export { Selector } from './Selector'; +export { Spatial } from './Spatial'; +export { True } from './True'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Duration.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Duration.tsx new file mode 100644 index 0000000000000..b22460dc6a2e5 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Duration.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, DateTime, Row } from '../abstract'; + +export const Duration = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Duration); + return ( + <> + + + + + + + + ); +}; +Duration.type = 'duration'; +Duration.fields = ['duration', 'origin']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Granularity.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Granularity.tsx new file mode 100644 index 0000000000000..9291fd84e4867 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Granularity.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { Duration, Period, Simple } from './'; + +export const Granularity = (props: QueryBuilderProps) => { + const defaultComponent = typeof props.options.builder === 'string' ? Simple : undefined; + return ( + + ); +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Period.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Period.tsx new file mode 100644 index 0000000000000..0c1740908c57c --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Period.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, DateTime, Row } from '../abstract'; + +export const Period = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Period); + return ( + + + + + + ); +}; +Period.type = 'period'; +Period.fields = ['origin', 'period', 'timeZone']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Simple.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Simple.tsx new file mode 100644 index 0000000000000..a964a00e641e1 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Simple.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { Select, Row } from '../abstract'; + +export const Simple = (props: QueryBuilderProps) => { + const { options, onOptionsChange } = props; + return ( + + + + + ); +}; +DimSelector.type = 'dimSelector'; +DimSelector.fields = ['aggregation', 'value']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/EqualTo.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/EqualTo.tsx new file mode 100644 index 0000000000000..36fc75b37220d --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/EqualTo.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const EqualTo = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, EqualTo); + return ( + + + + + ); +}; +EqualTo.type = 'equalTo'; +EqualTo.fields = ['aggregation', 'value']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Filter.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Filter.tsx new file mode 100644 index 0000000000000..c0e4d4379d1b0 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Filter.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Row } from '../abstract'; +import { Filter as FilterField } from '../filter'; + +export const Filter = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Filter); + return ( + + + + ); +}; +Filter.type = 'filter'; +Filter.fields = ['filter']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/GreaterThan.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/GreaterThan.tsx new file mode 100644 index 0000000000000..0ab227f20ed0f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/GreaterThan.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const GreaterThan = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, GreaterThan); + return ( + + + + + ); +}; +GreaterThan.type = 'greaterThan'; +GreaterThan.fields = ['aggregation', 'value']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/HavingSpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/HavingSpec.tsx new file mode 100644 index 0000000000000..2a7e881c68f76 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/HavingSpec.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { And, DimSelector, EqualTo, Filter, GreaterThan, LessThan, Not, Or } from './'; + +export const HavingSpec = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/LessThan.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/LessThan.tsx new file mode 100644 index 0000000000000..bf1c4b065e618 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/LessThan.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const LessThan = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LessThan); + return ( + + + + + ); +}; +LessThan.type = 'lessThan'; +LessThan.fields = ['aggregation', 'value']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Not.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Not.tsx new file mode 100644 index 0000000000000..47523adbc4d00 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Not.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Row } from '../abstract'; +import { HavingSpec } from './'; + +export const Not = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Not); + return ( + + + + ); +}; +Not.type = 'not'; +Not.fields = ['havingSpec']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Or.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Or.tsx new file mode 100644 index 0000000000000..d59456a9135c2 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Or.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { HavingSpec } from './'; + +export const Or = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Or); + return ( + + + + ); +}; +Or.type = 'or'; +Or.fields = ['havingSpecs']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/index.ts new file mode 100644 index 0000000000000..b9399e41c42f6 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/index.ts @@ -0,0 +1,9 @@ +export { And } from './And'; +export { DimSelector } from './DimSelector'; +export { EqualTo } from './EqualTo'; +export { Filter } from './Filter'; +export { GreaterThan } from './GreaterThan'; +export { HavingSpec } from './HavingSpec'; +export { LessThan } from './LessThan'; +export { Not } from './Not'; +export { Or } from './Or'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/index.ts new file mode 100644 index 0000000000000..8418bac8b17c7 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/index.ts @@ -0,0 +1 @@ +export { DruidQueryBuilder } from './DruidQueryBuilder'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/Default.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/Default.tsx new file mode 100644 index 0000000000000..c4283c52c5b12 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/Default.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { OrderByColumnSpecs } from '.'; + +export const Default = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Default); + return ( + <> + + + + + + + + ); +}; +Default.type = 'default'; +Default.fields = ['limit', 'columns']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/LimitSpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/LimitSpec.tsx new file mode 100644 index 0000000000000..26ac2e1eccb72 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/LimitSpec.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { Default } from './'; + +export const LimitSpec = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/OrderByColumnSpecs.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/OrderByColumnSpecs.tsx new file mode 100644 index 0000000000000..999b882e80509 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/OrderByColumnSpecs.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; + +export const OrderByColumnSpecs = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, OrderByColumnSpecs); + return ( + + + + + ); +}; +OrderByColumnSpecs.type = ''; +OrderByColumnSpecs.fields = ['direction', 'dimensionOrder']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/index.ts new file mode 100644 index 0000000000000..ed99129793202 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/index.ts @@ -0,0 +1,3 @@ +export { Default } from './Default'; +export { OrderByColumnSpecs } from './OrderByColumnSpecs'; +export { LimitSpec } from './LimitSpec'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Lookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Lookup.tsx new file mode 100644 index 0000000000000..20bdf760be817 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Lookup.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { Map } from './'; + +export const Lookup = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Map.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Map.tsx new file mode 100644 index 0000000000000..2cc5881c00347 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Map.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, KeyValue, Checkbox, Row } from '../abstract'; + +export const Map = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Map); + return ( + + + + + ); +}; +Map.type = 'map'; +Map.fields = ['map', 'isOneToOne']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/index.ts new file mode 100644 index 0000000000000..c6e30bf0b815e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/index.ts @@ -0,0 +1,2 @@ +export { Lookup } from './Lookup'; +export { Map } from './Map'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Arithmetic.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Arithmetic.tsx new file mode 100644 index 0000000000000..35d2491300fae --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Arithmetic.tsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Select, Multiple, Row } from '../abstract'; +import { PostAggregation } from './.'; + +export const Arithmetic = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Arithmetic); + return ( + <> + + + + + + ); +}; +Arithmetic.type = 'arithmetic'; +Arithmetic.fields = ['name', 'fn', 'fields', 'ordering']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Constant.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Constant.tsx new file mode 100644 index 0000000000000..8841fb099eae7 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Constant.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Constant = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Constant); + return ( + + + + + ); +}; +Constant.type = 'constant'; +Constant.fields = ['name', 'value']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleGreatest.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleGreatest.tsx new file mode 100644 index 0000000000000..b27e2ac5d73ce --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleGreatest.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { PostAggregation } from './.'; + +export const DoubleGreatest = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleGreatest); + return ( + <> + + + + + + + + ); +}; +DoubleGreatest.type = 'doubleGreatest'; +DoubleGreatest.fields = ['name', 'fields']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleLeast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleLeast.tsx new file mode 100644 index 0000000000000..7bd4a74eaa5d6 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleLeast.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { PostAggregation } from './.'; + +export const DoubleLeast = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleLeast); + return ( + <> + + + + + + + + ); +}; +DoubleLeast.type = 'doubleLeast'; +DoubleLeast.fields = ['name', 'fields']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FieldAccess.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FieldAccess.tsx new file mode 100644 index 0000000000000..a2dcf3767a714 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FieldAccess.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const FieldAccess = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FieldAccess); + return ( + + + + + ); +}; +FieldAccess.type = 'fieldAccess'; +FieldAccess.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FinalizingFieldAccess.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FinalizingFieldAccess.tsx new file mode 100644 index 0000000000000..c78e136755aaa --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FinalizingFieldAccess.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const FinalizingFieldAccess = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, FinalizingFieldAccess); + return ( + + + + + ); +}; +FinalizingFieldAccess.type = 'finalizingFieldAccess'; +FinalizingFieldAccess.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/HyperUniqueCardinality.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/HyperUniqueCardinality.tsx new file mode 100644 index 0000000000000..2434dcc508065 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/HyperUniqueCardinality.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const HyperUniqueCardinality = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, HyperUniqueCardinality); + return ( + + + + + ); +}; +HyperUniqueCardinality.type = 'hyperUniqueCardinality'; +HyperUniqueCardinality.fields = ['name', 'fieldName']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Javascript.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Javascript.tsx new file mode 100644 index 0000000000000..53437d9a30a60 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Javascript.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Code, Row } from '../abstract'; + +export const Javascript = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Javascript); + return ( + <> + + + + + + + + + + + ); +}; +Javascript.type = 'javascript'; +Javascript.fields = ['name', 'fieldNames', 'function']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongGreatest.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongGreatest.tsx new file mode 100644 index 0000000000000..506ee66f3565b --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongGreatest.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { PostAggregation } from './.'; + +export const LongGreatest = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LongGreatest); + return ( + <> + + + + + + + + ); +}; +LongGreatest.type = 'longGreatest'; +LongGreatest.fields = ['name', 'fields']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongLeast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongLeast.tsx new file mode 100644 index 0000000000000..39f1312706d5b --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongLeast.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { PostAggregation } from './.'; + +export const LongLeast = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, LongLeast); + return ( + <> + + + + + + + + ); +}; +LongLeast.type = 'longLeast'; +LongLeast.fields = ['name', 'fields']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/PostAggregation.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/PostAggregation.tsx new file mode 100644 index 0000000000000..40fa4fbac9a5a --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/PostAggregation.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { + Arithmetic, + Constant, + DoubleGreatest, + DoubleLeast, + FieldAccess, + FinalizingFieldAccess, + HyperUniqueCardinality, + Javascript, + LongGreatest, + LongLeast, + QuantilesDoublesSketchToQuantile, +} from './'; + +export const PostAggregation = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/QuantilesDoublesSketchToQuantile.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/QuantilesDoublesSketchToQuantile.tsx new file mode 100644 index 0000000000000..5dfd1f892a66a --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/QuantilesDoublesSketchToQuantile.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row, QueryBuilderComponentSelector } from '../abstract'; +import { FieldAccess, FinalizingFieldAccess, Javascript } from './'; + +export const QuantilesDoublesSketchToQuantile = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, QuantilesDoublesSketchToQuantile); + return ( + <> + + + + + + + + + + + ); +}; +QuantilesDoublesSketchToQuantile.type = 'quantilesDoublesSketchToQuantile'; +QuantilesDoublesSketchToQuantile.fields = ['name', 'field', 'fraction']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/index.ts new file mode 100644 index 0000000000000..d2e4502b0a927 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/index.ts @@ -0,0 +1,12 @@ +export { Arithmetic } from './Arithmetic'; +export { Constant } from './Constant'; +export { DoubleGreatest } from './DoubleGreatest'; +export { DoubleLeast } from './DoubleLeast'; +export { FieldAccess } from './FieldAccess'; +export { FinalizingFieldAccess } from './FinalizingFieldAccess'; +export { HyperUniqueCardinality } from './HyperUniqueCardinality'; +export { Javascript } from './Javascript'; +export { LongGreatest } from './LongGreatest'; +export { LongLeast } from './LongLeast'; +export { PostAggregation } from './PostAggregation'; +export { QuantilesDoublesSketchToQuantile } from './QuantilesDoublesSketchToQuantile'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/DatasourceMetadata.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/DatasourceMetadata.tsx new file mode 100644 index 0000000000000..84b0b3c27fc3d --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/DatasourceMetadata.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, Row } from '../abstract'; +import { DataSource } from '../datasource'; + +export const DatasourceMetadata = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderProps(props, DatasourceMetadata); + return ( + + + + ); +}; +DatasourceMetadata.queryType = 'dataSourceMetadata'; +DatasourceMetadata.fields = ['dataSource']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/GroupBy.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/GroupBy.tsx new file mode 100644 index 0000000000000..dc38d247691bb --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/GroupBy.tsx @@ -0,0 +1,98 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { DataSource } from '../datasource'; +import { Dimension } from '../dimension'; +import { LimitSpec } from '../limitspec'; +import { HavingSpec } from '../havingspec'; +import { Granularity } from '../granularity'; +import { Filter } from '../filter'; +import { Aggregation } from '../aggregation'; +import { PostAggregation } from '../postaggregation'; +import { Intervals } from '../querysegmentspec'; +import { VirtualColumn } from '../virtualcolumn'; + +export const GroupBy = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, GroupBy); + const scopedComponentProps = useScopedQueryBuilderProps(props, GroupBy); + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; +GroupBy.queryType = 'groupBy'; +GroupBy.fields = [ + 'dataSource', + 'dimensions', + 'limitSpec', + 'having', + 'granularity', + 'filter', + 'aggregations', + 'postAggregations', + 'intervals', + 'virtualColumns', +]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Json.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Json.tsx new file mode 100644 index 0000000000000..e06fe46f53fdc --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Json.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { QueryBuilderProps, QueryBuilderOptions } from '../types'; +import { Code, Row } from '../abstract'; + +export const Json = (props: QueryBuilderProps) => { + const options: any = { builder: JSON.stringify(props.options.builder, null, '\t') }; + const onChange = (options: QueryBuilderOptions) => { + let builder: any = {}; + try { + builder = JSON.parse(options.builder); + } catch { + return; + } + props.onOptionsChange({ ...props.options, builder: builder }); + }; + return ( + + + + ); +}; +Json.queryType = 'json'; +Json.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Query.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Query.tsx new file mode 100644 index 0000000000000..68bec36d9b832 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Query.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { + DatasourceMetadata, + GroupBy, + Json, + Scan, + Search, + SegmentMetadata, + Sql, + TimeBoundary, + Timeseries, + TopN, +} from './'; + +export const Query = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Scan.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Scan.tsx new file mode 100644 index 0000000000000..b7135e60786cb --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Scan.tsx @@ -0,0 +1,71 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Multiple, Input, Select, Row } from '../abstract'; +import { DataSource } from '../datasource'; +import { Filter } from '../filter'; +import { VirtualColumn } from '../virtualcolumn'; +import { Intervals } from '../querysegmentspec'; + +export const Scan = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Scan); + const scopedComponentProps = useScopedQueryBuilderProps(props, Scan); + return ( + <> + + + + + + + + + + + + + + + + + + + + + ); +}; +Scan.queryType = 'scan'; +Scan.fields = ['dataSource', 'intervals', 'filter', 'columns', 'order', 'limit', 'batchSize', 'virtualColumns']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Search.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Search.tsx new file mode 100644 index 0000000000000..99632d97280bf --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Search.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Multiple, Input, Row } from '../abstract'; +import { DataSource } from '../datasource'; +import { Granularity } from '../granularity'; +import { Filter } from '../filter'; +import { Intervals } from '../querysegmentspec'; +import { Dimension } from '../dimension'; +import { SearchQuerySpec } from '../searchqueryspec'; +import { SearchSortSpec } from '../searchsortspec'; + +export const Search = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Search); + const scopedComponentProps = useScopedQueryBuilderProps(props, Search); + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; +Search.queryType = 'search'; +Search.fields = ['dataSource', 'granularity', 'filter', 'limit', 'intervals', 'searchDimensions', 'query', 'sort']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/SegmentMetadata.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/SegmentMetadata.tsx new file mode 100644 index 0000000000000..dd76f48e34815 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/SegmentMetadata.tsx @@ -0,0 +1,93 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { + useScopedQueryBuilderProps, + useScopedQueryBuilderFieldProps, + ScopeType, + Select, + Checkbox, + MultiSelect, + Row, +} from '../abstract'; +import { DataSource } from '../datasource'; +import { Intervals } from '../querysegmentspec'; +import { ToInclude } from '../toinclude'; + +export const SegmentMetadata = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, SegmentMetadata); + const scopedComponentProps = useScopedQueryBuilderProps(props, SegmentMetadata); + return ( + <> + + + + + + + + + + + + + + + + + + + + ); +}; +TimeBoundary.queryType = 'timeBoundary'; +TimeBoundary.fields = ['dataSource', 'bound', 'filter', 'intervals']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Timeseries.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Timeseries.tsx new file mode 100644 index 0000000000000..cb740b0565e50 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Timeseries.tsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { + useScopedQueryBuilderProps, + useScopedQueryBuilderFieldProps, + Multiple, + Input, + Checkbox, + Row, +} from '../abstract'; +import { DataSource } from '../datasource'; +import { Granularity } from '../granularity'; +import { Filter } from '../filter'; +import { Aggregation } from '../aggregation'; +import { PostAggregation } from '../postaggregation'; +import { VirtualColumn } from '../virtualcolumn'; +import { Intervals } from '../querysegmentspec'; + +export const Timeseries = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Timeseries); + const scopedComponentProps = useScopedQueryBuilderProps(props, Timeseries); + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; +Timeseries.queryType = 'timeseries'; +Timeseries.fields = [ + 'dataSource', + 'descending', + 'intervals', + 'granularity', + 'filter', + 'aggregations', + 'postAggregations', + 'limit', + 'virtualColumns', +]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TopN.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TopN.tsx new file mode 100644 index 0000000000000..33e5de5d6dc63 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TopN.tsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Multiple, Input, Row } from '../abstract'; +import { DataSource } from '../datasource'; +import { Intervals } from '../querysegmentspec'; +import { Granularity } from '../granularity'; +import { Filter } from '../filter'; +import { Aggregation } from '../aggregation'; +import { PostAggregation } from '../postaggregation'; +import { Dimension } from '../dimension'; +import { TopNMetric } from '../topnmetric'; +import { VirtualColumn } from '../virtualcolumn'; + +export const TopN = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, TopN); + const scopedComponentProps = useScopedQueryBuilderProps(props, TopN); + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; +TopN.queryType = 'topN'; +TopN.fields = [ + 'dataSource', + 'intervals', + 'granularity', + 'filter', + 'aggregations', + 'postAggregations', + 'dimension', + 'threshold', + 'metric', + 'virtualColumns', +]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/index.ts new file mode 100644 index 0000000000000..896f90d9da31e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/index.ts @@ -0,0 +1,11 @@ +export { Query } from './Query'; +export { DatasourceMetadata } from './DatasourceMetadata'; +export { GroupBy } from './GroupBy'; +export { Json } from './Json'; +export { Scan } from './Scan'; +export { Search } from './Search'; +export { SegmentMetadata } from './SegmentMetadata'; +export { Sql } from './Sql'; +export { TimeBoundary } from './TimeBoundary'; +export { Timeseries } from './Timeseries'; +export { TopN } from './TopN'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/Intervals.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/Intervals.tsx new file mode 100644 index 0000000000000..3bd118d67e0a7 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/Intervals.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Multiple, DateInterval } from '../abstract'; + +export const Intervals = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Intervals); + return ( + + ); +}; +Intervals.type = 'intervals'; +Intervals.fields = ['intervals']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/QuerySegmentSpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/QuerySegmentSpec.tsx new file mode 100644 index 0000000000000..95a483a8c79ab --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/QuerySegmentSpec.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { Intervals } from './'; + +export const QuerySegmentSpec = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/index.ts new file mode 100644 index 0000000000000..8949c8cb2dcdd --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/index.ts @@ -0,0 +1,2 @@ +export { QuerySegmentSpec } from './QuerySegmentSpec'; +export { Intervals } from './Intervals'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/All.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/All.tsx new file mode 100644 index 0000000000000..7a4ddfe5b993c --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/All.tsx @@ -0,0 +1,27 @@ +import React, { useState } from 'react'; +import { InfoBox } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const All = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, All); + const [showInfo, setShowInfo] = useState(true); + return ( + <> + {showInfo && ( + + { + setShowInfo(false); + }} + > +

All. Whatever it does.

+
+
+ )} + + ); +}; +All.type = 'all'; +All.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Contains.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Contains.tsx new file mode 100644 index 0000000000000..65ecca4c902e8 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Contains.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; + +export const Contains = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Contains); + return ( + <> + + + + + + + + ); +}; +Contains.type = 'contains'; +Contains.fields = ['case_sensitive', 'value']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Fragment.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Fragment.tsx new file mode 100644 index 0000000000000..4e5eef1e2f12f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Fragment.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Checkbox, Multiple, Row } from '../abstract'; + +export const Fragment = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Fragment); + return ( + <> + + + + + + + + ); +}; +Fragment.type = 'fragment'; +Fragment.fields = ['case_sensitive', 'values']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/InsensitiveContains.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/InsensitiveContains.tsx new file mode 100644 index 0000000000000..0f3904fea9b72 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/InsensitiveContains.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const InsensitiveContains = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, InsensitiveContains); + return ( + + + + ); +}; +InsensitiveContains.type = 'insensitive_contains'; +InsensitiveContains.fields = ['value']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Regex.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Regex.tsx new file mode 100644 index 0000000000000..9bb9f16cfc232 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Regex.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Regex = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Regex); + return ( + + + + ); +}; +Regex.type = 'regex'; +Regex.fields = ['pattern']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/SearchQuerySpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/SearchQuerySpec.tsx new file mode 100644 index 0000000000000..9f6e1b5b8c26f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/SearchQuerySpec.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { All, Contains, Fragment, InsensitiveContains, Regex } from './'; + +export const SearchQuerySpec = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/index.ts new file mode 100644 index 0000000000000..776d4283fb919 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/index.ts @@ -0,0 +1,6 @@ +export { All } from './All'; +export { Contains } from './Contains'; +export { Fragment } from './Fragment'; +export { InsensitiveContains } from './InsensitiveContains'; +export { Regex } from './Regex'; +export { SearchQuerySpec } from './SearchQuerySpec'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/AlphaNumeric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/AlphaNumeric.tsx new file mode 100644 index 0000000000000..3747411ad1926 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/AlphaNumeric.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const AlphaNumeric = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, AlphaNumeric); + return AlphaNumeric.; +}; +AlphaNumeric.type = 'alphanumeric'; +AlphaNumeric.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Lexicographic.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Lexicographic.tsx new file mode 100644 index 0000000000000..b3db709f608ea --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Lexicographic.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const Lexicographic = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, Lexicographic); + return Lexicographic.; +}; +Lexicographic.type = 'lexicographic'; +Lexicographic.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Numeric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Numeric.tsx new file mode 100644 index 0000000000000..f6c6edf95f867 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Numeric.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const Numeric = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, Numeric); + return Numeric.; +}; +Numeric.type = 'numeric'; +Numeric.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/SearchSortSpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/SearchSortSpec.tsx new file mode 100644 index 0000000000000..e2ba2fb2db62a --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/SearchSortSpec.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { AlphaNumeric, Lexicographic, Numeric, StrLen, Version } from './'; + +export const SearchSortSpec = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/StrLen.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/StrLen.tsx new file mode 100644 index 0000000000000..8f29f727090a7 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/StrLen.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const StrLen = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, StrLen); + return StrLen.; +}; +StrLen.type = 'strlen'; +StrLen.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Version.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Version.tsx new file mode 100644 index 0000000000000..7636260ab81e3 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Version.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const Version = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, Version); + return Version.; +}; +Version.type = 'version'; +Version.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/index.ts new file mode 100644 index 0000000000000..db29a6e43cea8 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/index.ts @@ -0,0 +1,6 @@ +export { AlphaNumeric } from './AlphaNumeric'; +export { Lexicographic } from './Lexicographic'; +export { Numeric } from './Numeric'; +export { SearchSortSpec } from './SearchSortSpec'; +export { StrLen } from './StrLen'; +export { Version } from './Version'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/All.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/All.tsx new file mode 100644 index 0000000000000..42fbeb0605f1d --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/All.tsx @@ -0,0 +1,27 @@ +import React, { useState } from 'react'; +import { InfoBox } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const All = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, All); + const [showInfo, setShowInfo] = useState(true); + return ( + <> + {showInfo && ( + + { + setShowInfo(false); + }} + > +

All columns should be included in the result.

+
+
+ )} + + ); +}; +All.type = 'all'; +All.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/List.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/List.tsx new file mode 100644 index 0000000000000..7cc9f513de30a --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/List.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; + +export const List = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, List); + return ( + + + + ); +}; +List.type = 'list'; +List.fields = ['columns']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/None.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/None.tsx new file mode 100644 index 0000000000000..c95f69c9a7d25 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/None.tsx @@ -0,0 +1,27 @@ +import React, { useState } from 'react'; +import { InfoBox } from '@grafana/ui'; +import { QueryBuilderProps } from '../types'; +import { useQueryBuilderAutoSubmit, Row } from '../abstract'; + +export const None = (props: QueryBuilderProps) => { + useQueryBuilderAutoSubmit(props, None); + const [showInfo, setShowInfo] = useState(true); + return ( + <> + {showInfo && ( + + { + setShowInfo(false); + }} + > +

No column should be included in the result.

+
+
+ )} + + ); +}; +None.type = 'none'; +None.fields = [] as string[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/ToInclude.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/ToInclude.tsx new file mode 100644 index 0000000000000..592045f8dfdad --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/ToInclude.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { All, List, None } from './'; + +export const ToInclude = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/index.ts new file mode 100644 index 0000000000000..675b56a504e89 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/index.ts @@ -0,0 +1,4 @@ +export { All } from './All'; +export { List } from './List'; +export { None } from './None'; +export { ToInclude } from './ToInclude'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/AlphaNumeric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/AlphaNumeric.tsx new file mode 100644 index 0000000000000..831fd241a37e5 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/AlphaNumeric.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const AlphaNumeric = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, AlphaNumeric); + return ( + + + + ); +}; +AlphaNumeric.type = 'alphaNumeric'; +AlphaNumeric.fields = ['previousStop']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Dimension.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Dimension.tsx new file mode 100644 index 0000000000000..8d52ea7221d65 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Dimension.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; + +export const Dimension = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Dimension); + return ( + + + + ); +}; +Dimension.type = 'dimension'; +Dimension.fields = ['ordering', 'previousStop']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Inverted.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Inverted.tsx new file mode 100644 index 0000000000000..d65499eece148 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Inverted.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderProps, Row } from '../abstract'; +import { TopNMetric } from './'; + +export const Inverted = (props: QueryBuilderProps) => { + const scopedComponentProps = useScopedQueryBuilderProps(props, Inverted); + return ( + + + + ); +}; +Inverted.type = 'inverted'; +Inverted.fields = ['metric']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Lexicographic.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Lexicographic.tsx new file mode 100644 index 0000000000000..adef0a4715985 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Lexicographic.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Lexicographic = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Lexicographic); + return ( + + + + ); +}; +Lexicographic.type = 'lexicographic'; +Lexicographic.fields = ['previousStop']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Numeric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Numeric.tsx new file mode 100644 index 0000000000000..7578d4a568d4b --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Numeric.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; + +export const Numeric = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Numeric); + return ( + + + + ); +}; +Numeric.type = 'numeric'; +Numeric.fields = ['metric']; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/TopNMetric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/TopNMetric.tsx new file mode 100644 index 0000000000000..70acf4ce3dd22 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/TopNMetric.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { QueryBuilderComponentSelector } from '../abstract'; +import { AlphaNumeric, Dimension, Inverted, Lexicographic, Numeric } from './'; + +export const TopNMetric = (props: QueryBuilderProps) => ( + +); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/index.ts new file mode 100644 index 0000000000000..d4310c159470f --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/index.ts @@ -0,0 +1,6 @@ +export { AlphaNumeric } from './AlphaNumeric'; +export { Dimension } from './Dimension'; +export { Inverted } from './Inverted'; +export { Lexicographic } from './Lexicographic'; +export { Numeric } from './Numeric'; +export { TopNMetric } from './TopNMetric'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/types.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/types.ts new file mode 100644 index 0000000000000..39e3f54966fea --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/types.ts @@ -0,0 +1,9 @@ +export interface QueryBuilderOptions { + builder: any; + settings: any; +} + +export interface QueryBuilderProps { + options: QueryBuilderOptions; + onOptionsChange: (options: QueryBuilderOptions) => void; +} diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/Expression.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/Expression.tsx new file mode 100644 index 0000000000000..a47e30d2ae787 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/Expression.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { QueryBuilderProps } from '../types'; +import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; + +export const Expression = (props: QueryBuilderProps) => { + const scopedProps = useScopedQueryBuilderFieldProps(props, Expression); + return ( + + + + ) => onChange({ ...parameter, name: e.target.value })} + /> + + + ) => onChange({ ...parameter, value: e.target.value })} + /> + + + ); +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryDefaultSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryDefaultSettings.tsx new file mode 100644 index 0000000000000..080465a14eabc --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryDefaultSettings.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { FieldSet } from '@grafana/ui'; +import { css, cx } from '@emotion/css'; +import { DruidQueryRequestSettings, DruidQueryResponseSettings } from './'; +import { QuerySettingsProps } from './types'; + +export const DruidQueryDefaultSettings = (props: QuerySettingsProps) => { + return ( + <> +
+ +
+
+ +
+ + ); +}; + +const styles = { + fieldset: css` + padding-left: 5px; + `, +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryLogSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryLogSettings.tsx new file mode 100644 index 0000000000000..368bc4c6420a8 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryLogSettings.tsx @@ -0,0 +1,69 @@ +import React, { ChangeEvent } from 'react'; +import { InlineLabel, InlineFieldRow, InlineField, Input, useTheme, stylesFactory } from '@grafana/ui'; +import { GrafanaTheme } from '@grafana/data'; +import { css, cx } from '@emotion/css'; +import { QuerySettingsProps } from './types'; + +export const DruidQueryLogSettings = (props: QuerySettingsProps) => { + const theme = useTheme(); + const styles = getStyles(theme); + const { options, onOptionsChange } = props; + const { settings } = options; + const onInputChange = (event: ChangeEvent) => { + onOptionsChange({ ...options, settings: { ...settings, [event.target.name]: event.target.value } }); + }; + return ( + <> + + Log columns mapping + + + + + + + + + + + + + + + + + + + + ); +}; + +const getStyles = stylesFactory((theme: GrafanaTheme) => { + return { + row: css` + width: 100%; + & > & { + border-left: 1px solid ${theme.colors.border2}; + padding: 5px 0px 0px 10px; + } + `, + }; +}); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryRequestSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryRequestSettings.tsx new file mode 100644 index 0000000000000..4bd4a37c304ab --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryRequestSettings.tsx @@ -0,0 +1,29 @@ +import React, { ChangeEvent } from 'react'; +import { InlineFieldRow, InlineField, Input } from '@grafana/ui'; +import { QuerySettingsProps } from './types'; +import { DruidQueryContextSettings } from './DruidQueryContextSettings'; + +export const DruidQueryRequestSettings = (props: QuerySettingsProps) => { + const { options, onOptionsChange } = props; + const { settings } = options; + const onDebounceTimeChange = (event: ChangeEvent) => { + onOptionsChange({ ...options, settings: { ...settings, debounceTime: Number(event.target.value) } }); + }; + return ( + <> + + + + + + + + + + ); +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryResponseSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryResponseSettings.tsx new file mode 100644 index 0000000000000..eb47082b9ce4e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryResponseSettings.tsx @@ -0,0 +1,67 @@ +import React, { ChangeEvent } from 'react'; +import { InlineFieldRow, InlineField, InlineSwitch, Select, Input } from '@grafana/ui'; +import { SelectableValue } from '@grafana/data'; +import { QuerySettingsProps } from './types'; +import { DruidQueryLogSettings } from './DruidQueryLogSettings'; + +export const DruidQueryResponseSettings = (props: QuerySettingsProps) => { + const { options, onOptionsChange } = props; + const { settings } = options; + const formatSelectOptions: Array> = [ + { label: 'Long', value: 'long' }, + { label: 'Wide', value: 'wide' }, + { label: 'Log', value: 'log' }, + ]; + const selectFormatOptionByValue = (value?: string): SelectableValue | undefined => { + if (undefined === value) { + return undefined; + } + const options = formatSelectOptions.filter((option) => option.value === value); + return options.length > 0 ? options[0] : undefined; + }; + const onFormatSelectionChange = (option: SelectableValue) => { + onOptionsChange({ ...options, settings: { ...settings, format: option.value } }); + }; + const onHideEmptyColumnsChange = (event: ChangeEvent) => { + onOptionsChange({ ...options, settings: { ...settings, hideEmptyColumns: event!.currentTarget.checked } }); + }; + const onResponseLimitChange = (event: ChangeEvent) => { + onOptionsChange({ ...options, settings: { ...settings, responseLimit: Number(event.target.value) } }); + }; + return ( + <> + + + + + + + + + + + {settings.format === 'log' && ( + + + + )} + + ); +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQuerySettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQuerySettings.tsx new file mode 100644 index 0000000000000..007f378e01051 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQuerySettings.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { FieldSet } from '@grafana/ui'; +import { css, cx } from '@emotion/css'; +import { DruidQueryRequestSettings, DruidQueryResponseSettings } from './'; +import { QuerySettingsProps } from './types'; + +export const DruidQuerySettings = (props: QuerySettingsProps) => { + return ( + <> +
+ +
+
+ +
+ + ); +}; + +const styles = { + fieldset: css` + padding-left: 5px; + `, +}; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/index.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/index.ts new file mode 100644 index 0000000000000..e882fbe0a4012 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/index.ts @@ -0,0 +1,6 @@ +export { DruidQueryDefaultSettings } from './DruidQueryDefaultSettings'; +export { DruidQuerySettings } from './DruidQuerySettings'; +export { DruidQueryRequestSettings } from './DruidQueryRequestSettings'; +export { DruidQueryContextSettings } from './DruidQueryContextSettings'; +export { DruidQueryResponseSettings } from './DruidQueryResponseSettings'; +export { DruidQueryLogSettings } from './DruidQueryLogSettings'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/types.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/types.ts new file mode 100644 index 0000000000000..5b2c38c5aff77 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/types.ts @@ -0,0 +1,23 @@ +export interface QueryContextParameter { + name: string; + value: any; +} + +export interface QuerySettings { + format?: string; + contextParameters?: QueryContextParameter[]; + hideEmptyColumns?: boolean; + responseLimit?: number; + logColumnTime?: string; + logColumnLevel?: string; + logColumnMessage?: string; + debounceTime?: number; +} +export interface QuerySettingsOptions { + settings: QuerySettings; +} + +export interface QuerySettingsProps { + options: QuerySettingsOptions; + onOptionsChange: (options: QuerySettingsOptions) => void; +} diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/druid.svg b/public/app/plugins/datasource/grafadruid-druid-datasource/img/druid.svg new file mode 100644 index 0000000000000..52db86db3fbb9 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/img/druid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-datasource-connection.png b/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-datasource-connection.png new file mode 100644 index 0000000000000000000000000000000000000000..f7066ab4702e3b7fb4342a0c390086b17ace4c10 GIT binary patch literal 46106 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 P+b*2HGARr}yNbe|3N@$^n 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�@PROHj}1Le!kol&EZH-q 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

#w+LP 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 z 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 bit4GE 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 literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-formatter-druidjson.png b/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-formatter-druidjson.png new file mode 100644 index 0000000000000000000000000000000000000000..3bdf32a1b8e95d56f876a5768934f91220fe971f GIT binary patch literal 139220 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 literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-json.png b/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-json.png new file mode 100644 index 0000000000000000000000000000000000000000..946b319e4f00b7ca02b21e414a4a0c2e095c885b GIT binary patch literal 190197 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

I+opGf=G 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 W-%UhYdRulct0=FA&XT=;|9=4U)8yX( literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-settings-logs.png b/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-settings-logs.png new file mode 100644 index 0000000000000000000000000000000000000000..4541be6e33be9ecca362492636cf6517dfaa3e9a GIT binary patch literal 84985 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 D1i3J{ literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-settings.png b/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..2ac0a0ccac7b865bcb1df0821a6ce90ef0037c8d GIT binary patch literal 185714 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�?!1sIn?XG0moyh9<{QQEXyCCAX{7Ikq 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%0AY#39 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 z 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 z zwX#*gA1{j;LCpCYc5rw^q{Hzjo6{MvN@wSWK8{Kx9O!z@vAt*U?jCH&XX3;Ol{ zfqnQEGZG{o(CVJe_xE7c>V7Hif9Zh!Q_$;~eH(io1hecaly*FtE?L34bZtKV<4wN2 z;loR&Zm*I|)1Ix*J0sVTX$f~@|C@jDzwGbvmILTD7vR77a$}hLUU3q(SX9IYNw7#T z=BPr%A>K_NG9661P5f+ZD}}*x-bf9IiQPZ9ol~=pr!CRB)b8JcW;5Ui4m?_dxf`*= zf+W0Oo}q+KHRZIm?L@t2)`Q=Ghk?a*TfQtrQGb5!=`b+izJDQDa&Kw7V8rLQRLoZ%Sz+ zc^d1xWjgi)pDGa`fibx&WeVMmk?-_Uvg97eQMq6yT3dnWqpkT(Eg?Lx7doy6Jf~5N zr_uX~Xgox4K@U&eRO2^|u>{Ueo-_49tLP{wiWj5?)(B9DiNVLKp;wPY`_X1l%J)OP z*P__IIw>}`$hI}WY1-X$xj=`bygWlvhJZ=1vZA7wX#4DdtFhR1l&rANbvpG^<&^C{ zIC@Hq%3N%zhYL|;u^Nu^R02d@05j9=aB?Of*uVN@4Km*rlE`7+2KY4M3%6$)M~TQi zSNdlenI2=HPm=Rpx;7mw{gPNMKj&mSpC0=EM9iG^e*Fjz$~c#Ea2OsQomSVjuPXjJ z+osi+@Fnthp(lU2-Dw5SKE8pG;qvB;F>5>lw5la4_NX(kZ+q-ub?W#&snWnFU(5p} zE{HouOG&oibWPU+SA-?#CZBEFb}(@08J}Sa4qELjlXVa6QafO)Y_MNrX4IX)Qd0-zucXh-fo<>Su zn{3`gXtz2seRaep_$@b|=O=O2B1RUQaB1X<#x2YRwY8L#cE>|V=i7qs<~JgH`6dM? z8$3Oea&qR|LP_}?E%a4Xq*n*vL!~pzlVu=e0(!Dn&V^vrAK6HwmYhN&O`8YZJ)jUn z!A`^vqz0gzn@@ZjOFQg+FwlsW~m4L7>0#_=dBb%mpntR>2J$jrwfg_ z-QL>zxMipL)U&@qk3~xi9Eyx%x?hHehc8beB*@qs7a#A+TQgiXk0tp2w1-qnD3RH@ zlV_Pxx8|&*QSjhf>P?9F=KCT*`~xsp+Vzgeordu$MO#;wk#an(WUBVD7!@@&5AU;@ zx;$+N1c!z20V$T1nVBjC>FIgsCxm?`-@wC$yRE_fw6MxHqr<@MG|}l~X7ZCPlY)Z0 z`!4hXLm)UfkWW*Sl5&@EbftJ6q!6z$MR;=NLl5&^J(=}Yd#43zNiZdWrJ*Aq?3bQ_ zRjK|064ib(a|KtTCCs9mEQrfn>R9QbN-|`PdSeCOo*kJN=t9)gl4D}j)YNDx;hFNJ zaZwx&6GQz?w=o|b-9Q<3MN`pGb;q%t26QoPzh=1j{*OF_cvPvbZD%ABxFw}KI@I!N zXsj;;ft_(NdG&@quuY+DzQPX!aSN8KB^dxJFV?igFLiEilmAEDrj~dlf972;&wiGC zyvv5Vp_^NsUs+j&z-i%fG*jbIFJFVQ8uS7LV>rMnHV#j7&CLP=0)7mRHGMp*oOzEt zqb6wQn_ovb6xQu*ho@5Fn7*q`K5tj)iiWy$1VrUC^u%-J^&x5{#dHCq6z{njVn5#% z0_j0iE+Z%7jCT$KkjU3up#& z#qG)83JO+dr2sJsH5L`A4$+++HNOkd%mn;~#tO7ol`&KK@VrtTW}|M~9Fk@xESuO2GrOKipV2P$nuJ9RJx(n-i8R8e zTymm-`}+X>2JGNdn_hxK={QMo!DU50@idg0D>1l@E|dIWn*alQbLYO@-;Ml+$Rz?y zO8s95a25S!#)ZrBKj9=l+#+gL=(OJ7KY*H>n_o)3UwQbXq&?7fG=;*D!+Fra@2f4C z|0{>=vdaHqFZ&Ai;wm2@-U29Y*Ni9OWQ;Ij z4Z*%JWO|2DsWWi<8yXsBHC~&OguI^>QeK=48pQV;#5A5!3kaNNXC*!U5Pengo1cWr zUL|B8SOfewqi?zPV8Z+<;@S|zpfT1-$urfovDvM0Sf^1)AY9eG{vz`wMN3DUaTE+) zaQ}Smc7qmVcsa?npr~jk@;5k!HRQ$^io{%YR%i*#5HZqS3&Sh23U5pj5%EdOr}v5O3+S#`gef=Jp|$fe>&; zSf-|>xgM<(qMa1N#rWc%(kLf_?_oF_Pko;AdW3=g6mg9+VLUco#kiht!cd&+f&X79 zdO%ZQqu+F`?Dlt5r$k)t+n{`S`Te>J3{J;^{{Gc-0nb(QH62jL%f^O=QPI&LwkmNM z{a-H+-Sd$y8rs^_$FMq~8uzA1-Nqk$ngzW}}a&8C$HxRsZnJ1@hr^%w)R zL0c)Z@obR^P;Lihnd)ah6O(zK?fz5iA{*bB(K9o(G|HYo%yxtl*a#|)lh?5p7kZbD z`W|)yw@2)FOr!RbFY9t;^EW|*V*o_*l67KXxvLC zm9(SD^e99A{F?Rvk?(mi!ecYQiQ~Mqd43-RwkkM{a8#ThXCNqTd&_=Ts|@OsM0eJV z917Ai7Fun6^@ur7rxEisZC&UW3%o!LPQ6;j60FuxDmQ0*%w=gIW3m{d=swZlJZ{1I zA}&V2-J+ybk5_a2Y?@Yl7->mqyWPWMZT$kqM{Q}~;+9Lhlf0Qxi~0JKLiH2lmhN48 z7Nrr+?F-}W-n6uuZT{^GtIhb=n%Gb7mK70E++_~L4#a3{;^ZtLWwMzJftwl+CMvKh z(#9DpaJ$bX*e7hE^fMFVp){IdFfTeNf|&yXB6e z`%)Z~E)x0rQ61DbLInv9@7cwv6m%kop$7)%4wi-kdGF4ge-YA-Z(=%_^(|I$t z$KvcDt&42B>eov3me7`IQCzTy--E9G(a6Pf)9nnwm_~b4kTrkRLSv&1C3Zkic`wKQ zZ>(FW_H8pGBh8EEr(GV%HXA4%rH|jR>jlsbR@IQ0b9)^dj-az|}mBRiHn3B`6&Z+_k+)0(@r1>%({pEvgaia|fO6 zy$)DaqE^uN*7A}PFzOy7RwDbw`?iAoQ-j0X#P+_^=XpxB(jtDvZ6L=f%^8I_q}*%v z7b+rA*RyJLF^0YN6f<#HuA+;zLqYJ-h${{7Yesq2Bvm>cVNRH;}S;ANrfu_zf44ogf(*#dcg2YEz z;)=uuxkyW)KFnb~v#g)aRB+;VvOe5G^a)+KolRbGUD2j6l=Xf0{J{CA3kwTp2bGQI zdy+^bG7z5umSk3f{lki7y57vn#^W=>EYe=&&Rh013;f)dh3gJFTiw4N_}s7+yAu}Y zvALVe;pDCxAYVzmsS1A@k1tqe`qHAspx-z%zFlJ(=3H=?$_np6uP-Q_A#f#zlqdZI zRajbV=WKI<-l1TZ_i0v&cuDJ1H8#gP$-PrgtCnE4G6{vx?zNp3iCw)3dfKRaoj`J_ z85%BjF*R-=T?%>LPULim_(^gxvBv-AJLJMVHK1t0O46kE!4@IrkXIVAX&2%eY*oKQ zA3?D!R1h+v(^7op5&k- zC$qP+qO~P*RdpBF=bOY`e&AQGDiccO987G=A`TOVOVE;&oX%Rz5e3g3L zlN^Wdnj4WmMHGUX{pEA}pytflL;GTPV5A4{7Ouk8w)Z9V@@0Vo#=#QSb=@p)YI>PF z{LIHsj4~iq?)|T!-J^x@xebcsghZ=xWsOI~k<9}t$aAe{_s>DhQ-DPQ-O#%Id{BEV z25+K5EQU)WRW^*q=M{(LMRqTPd7uIH#K?Sc?1TMfZl>}F52{4<^X+>0S*(&tR8!46 z_c0UJ*ol!1A0FP5^uZ3Nij#Mt@EOhv-3-NiJ^;Hfpf%bPvFKv`q|QU5LAQ|4$@ERa zX;BrOEJS?fl`yU*O0NA2ZGq$_Fe=nuzdi#Aj)%(zTr013?Wr>5l$1R9YQtVs;T?(w zWWIGU#>mi6-SJX<$9?MQ>B*vevuW5~UDNEZ-t%BZ1oR>CjC)b_Nx`uv@?G@{Nwf9S z&-HuU^9sJJLW0$U21EBLDqiCwN;7}`j7!qF9q)sEYR30N#(sb8W4C=^o*17CzeA7r ze4dah8HLY7rJ0km*)53O^XP@nu$A2HguB(0o~K898si6JZ09KWrD=%#-q9NxTD~PX zR_9!PvfxgQAMv$*bbpP{`0VTMy+hu_t><`lZ18*>j*0R0Q+QHUO^8&u0dxBIZL+`f z_d~AqYH!|6M&rsj+$v3xqjMBh(s}!g_Wmgr6T3srJc;7aNo8!~aeU+Mu^XS`hLj^V z+INGo&4UFG(i>Ha!6)0(-Kvr$;h?suJ>^Va+h;PB@f-O18}!b*L9}M>*YfI~OKB_Y zJ2PeP`89-%1UPT^Z%{0L&+fHp!!1YUTMp+y)<+8)FHolrygKgg z+B!hRWzQw=L$`DwD?tBx~s_5S~$#iIXyh0Z*@atWC+TmJd@ z(`vu_x31Tiur}R)RHZqQm)9shHi2l#jh2jW-%Nld`svdr5x0efZW{H# zkW+Sj^~e#eWcLG&lG3Yh3G1b|VJ@DZ9){KxWM?}cj2k=fCg$Ww2eCJRv!Fmuk!D{k zTD~i74UJ09>`|m-dPYXRR^`@Ewn|z~2aujMCzkH+=f9U8Z_*SxU2$~2Q>DwjbO!Px zp3@R2mgVK;o@evqlJ1&NsF1RXf(wTR5L6HUGZvME_2YW-ziesdUqil~o}4HoaNBH6 zRUhv!gJ=V=I!s`WNS~&rCJ^V(q!xiE9ydh zFEIq|H8nNm;o-ToS^JjFO--d8znO!und)liz9a!^YU=;Y7Bv6J$5@NNALY6fXT0H9 z`=Tp9KOdx7*pr_QV0q|2Rpxq~k?xJHa$3sSh?X@q-wz}a^1JZWQ>$*JOLPTB!beAA z!oqBNXm4N5L*anIc!m+M^jN3uwUTHNB+YuoKTG(l^$}Je+TLxedil)5)6Q;x0Utyx zkGx@xv)a>zpjok?r_qmJ0?}3)$~A1yy}HINmu?nBV}q0CY;OYzS~=elE2vbH9 z%$c8*XlUuYwFtpgU;+BIe+#iQ%6+OKeff3gvN|acMZ;qTQp&x$ris1lO8F0R{XZ=L zJt;@Dpmrk`{xX}lvm5LY1O3zM&PYUQ@$Rs!(M-AC*2SrB1S*9Ub#KPm!dbU>(Kx)W zYJRLptzoGw*~1k!A)_wUmdsNHB(=AgWH8ugLC(G?ZNpK zAg3%6u=#4b%oHwk4i~~BAfV-wq7*oNvnqi1Db92$+0$6G1_%Pls6}UIHj=^y*R2@7 zkowc{j4&I;C;S^xX-b>2fx!oze8#BN8LW#wF7tWm)KO`ni{8%{>rARLgNtF?{1tBU z8e0z9awKil)9bdQ^@fYj12!v-V>6TdVcm-!*3r2W@#{h3_f^BI8lafon&%FFlUKyt%LshZsWX(fM6sbu++I3Ndx z{X>uQY;(Sg!Kl8~JJi%7C_NC7=ShNyiQ&7_0^=)gMv&_Uu z#0}ITCc7in(KcOo4qXpN{BNGPkxC)UvAUXmD~^VWbvLy}>jZvi!!!;^+zi5mCo8Sh zAP_mKM;Ki%sUHu!O@DD2=FRB3A3)Guq8?n5r(M&p;#8w^XLn_El=OH*&v^2UMK7*r zwa1L)vIDPa)0}piQgYH;zM96b8@(WfK-qShUBSy4by^Ospy#8Ev5CnfaTQfw$~%T>7nZaXRM>HhXTzE|PQslwG@y zM1t;fd%WA{vqwLFZJY&(%kBxD?j-aP+oo$_xSSsacK7y89S$5*pJ_7w;(rnk$aIGHR!JDSRJM_+*-i`1w6t-FlbEKk+Cy=f14%=#0+ZGFND@UH#ud z{%$W5Ox77rWjR@~*^DKG@kwM*%5z35Ce!~5$=!~yZ@}WgcO|VJWZ}8AJOaR+{@Q){1kxN9yAS!t|*;6oSvqOJ?__s*72!%K%y|?@H^wwQ6Hag$PElf3NDBq*k zH4{1o|7>$_`Ulg9db~VX#bxk5*G=ZKUwdztXZ(pu+9`5zl+1i1T zvt5*t4hJY!{Z~AeRmU`hnTrAZhc73CUvMnONw@vJ`hFs2sX}-SI+L|986iqU%Pf(K zRABV{oL0^4eY!ZDQLT6re;$#$guiS&mMw_(krf_E#%jXmJz_+#g;3MZ5h6@6@ zB%M;=sOD;SaUPmyV!4sa2cJFs+?Gr}Nt!2-_VvRHpI4Bt??~LV-uv|fz^bEJ|b+)#)0$pO}WTaBhI#^=f4rBzG{qYI7f~dI0dYb1WyeX)g z-qibgV=yRXg z*)l3l#UItaXOe=o+}caeYfGP~z6y~@m6%`5Z|{{mU5G|HixxL~dlg|*G9Vs5r@nn= ztFCH+x$i^DS%AO3@paU5ws*PPam)Fl`%N-e1!}?eO7Bpi0<8`X4!%UrB&R*LU1v_= z$*7^RvDg-=4r=M}@pJ+a^`4Wl3Md4Aki0fkQX!?9YAHY#IL_=DvadYZ|KW5GeO5hi zA&mCtEfFA$3K-1qoi`Pwifu!++>ofbSg>_`QA=WDJ9mSpVE>qp04MMHy4gC`7|I$B z9NneuW{U=S;{iUMjQX7wF&&%){gRRMgN+1Rqze|dbg1LeGE>wgbP+Os!=0>Nx6?C77SW-R2z8s5DN8{1G&uKUg&aHK0ys%6i{?T%KLnSf)gF_cNn&!N^prqcfVM&C= zImHTxpAKeTHj?;%yDz)Pn6SwV`~5W~)#vHUM*gfPliN}7!F*XY{5GOI;2hKf@2}6} zpcLfrlGeWRy<=yA3Hdx=aAw96`EzHdsC`~qHEH2wvOT7+vtpe}`p#~0gD#GL&TR!p z54SuAsHLR3zm=}empH4iC=Q}EAB@%e+|UD(rLymf-;uYTQQFRH_5}{7)B=bqW2Z4Vuy8}BcvfD0{ulLwx}QBZiTe3 z?5a$g1#qX9W6#dqDkl*W6TH=dSF>)8Dub`|VO0WxlN3w0mhnH@>M1WTr}nnn6D1E| zbU4}D_uoYSF5hKUsdxe)-#M1GMr$@L(heC=%eyXFFVfEM?5At+s8Nzafsv`b49PR< zL@H@udcD3vj+lX`iJ!)iZl+=*#QfrMmn~JQSQZZk+SI?m1NA1S_%giU%>;-tAhcXi z^7t!H(F!tUFOM1eQ-sa_pB3OAqQ}gnWS)-aD8=4Gd(2>tx3b8+?u{<2`RU^&7P7!A zi8kc}41zj~@e5+qS4v$ca>VdV52|L7z1l)~$I>9t!8HR=a5c zYmXFD5=5%37dDc)68npV$I}+Oc@;5XAE5t$WgdIWbS82=y5sxNmX7W|#X?5`uD{qP zY?{T#jbHw%mD4Zoc3fG6zq){;!_Uo4h=CqKY9Mp;Z-CG@vDAq#T#q2-W4}U^G?2^g z@_2@&f%~jyFBjqSmgNMlpRh|yHUOq$XUyF#;ePnxqW(rOPzw3(l|GZP>!ER1$V6@` z5_1+ZmT3hSZt~6yZ{v#OX~EQ#qL+&vyP}`hVsbhiIJfgy1EPTg1TuWEISGLzGJDby zMtjS!=N#8jAUk=D0&Ny2Zk6t{rG>44t#u%GM5Bz#b2ePNv~|Jp*esN@7QIeCf1|t1 zx~{U@g5@3snM(;J=g}#Yy#IAioGG-XgpO_UE%TbMPQ%1gc~Nhm8eI)wmCZFkL7)Aq zP`x-cJ>B5^1Zh560FrQ+nwtlDMwFz=*@ot{>V++?uPnIM?@O{fU>-iW<%8|pXCI1D zpaWA=PAD&|*!OPkkr6}GG#tHl_oO3XA+#5fN+vTGu+Mysu$ri=+3AlfAR-!(&%JjE z#AZbRMCf9*R92$i$|$w zJ??Rj`$r=_Zom4n!qZjdrNC%bD@{$!Nzh)1$zs;a-0GmvmFy1aoZuT+N2Uta^&ab?TNZ(Wv*L=9%L* zWxvZnUMUAL4IS7!RRXLxx;OaIuFL|r+a8!+qkq@_c^A?>Sk4l+Sv)Fk;Dj@nxcQg@ z4e7~8aq_;jhM+&RG42b=6@x@0(s*%xYS>E*_uU@hhKsXJEfAu|b2`x~7f!EaCQ3S{ ztXL-xIOLmrokJt$ns}s8rZU0;@gAcl<{aXleo*B;Q^!pB$Rv^}Rs?_$sy&PRMcN8h z^!nl1)n!D+SXU@%o>pYTiFRN5J|vjeZP|XPP>D7^ig6~(X>;=I6ai}~;XaB9_69xUnO#kb7iF@k3r#;S zk5A|+4Gp|__dQO=rnAHWESOs zc)xh;z>nBU+GA+-LjOV!Fb^C zSE}dh-w_E);aa-zI1pDWP(r3}Gdd5>8;p9+Fn5Zd- zIytbjDKZC@72-YI?Fji$T}TSkWlm?$6AFW{umOCb%e>HOt7xu_XH*D67N8L+12m!S z(BE-8()c2v%!>z1-2tg&&Jx=)2WYNNuuX)ny%Is}Px=5(bTE7g^}!wRz}!~PL${YU zbJmfmd%AM&G4#Q`SaF2BB26KhP|~Wd z)&4d+;)gMTI9G9Ev)z5!*xr5w@KasF%dVLW)B|yAVqMT<545cTV%0!(P$hSHSdWGF z#;e>_@3xHHxl^w}*D%Ffbt7IfbIhGE{%O7wPsUU*;1mHldI^gGMLDjy=6G_scswB* zjkx3Y<8xk+J{chMDi_j)I_^z3i-gK6D_4Sft$*i=;*(V{Ev-eejLR^YI@@pxi@!n@ zuXTP`_5676bzQmggcj?%S_sJ|`QHhx`)v>2sP#pzE<}$64a4KDh!7|9^NUwsXFa!T z=+FGNBRW7%A-TJ=GdDlqV>#J(1F+JywY7bjQZ3M=6iUz=<*)64@}1`9=|dQga!i;B z{=WD5c~u$3s*66^WBe%6mCPwkCA(x+Hv`h5W{%ChYWQTaeP-7ts{7tbdxlTK2eAB< zGVf_|jg1VB1JFC}gU}FV+m0&Kw%Lfu=8P<$)huLVHF9)u0{f%_MG?q9-ax`=)n|~n z1W4rHw3)~_!C-u)p=NfZfP>sQR>J21?+JmpYWRRZH2gbD*UJU|{#Q5;L~e z)ZXG12(&cH>e-p?5hez-@dOZ_xF1X?$;vXkcroo*Gsm^RXa()*XCG(9Lgy#o=_ACy z>+_U?c6YF%TJd?pSq^KEr(3PXRNDixl;c0!L!l!N72vA}cOmy(R+4LQ+}uhXhA9d( zVk!XlbJj?cNMIF4x;=e-)B<-2|4^+1^)P^**CaA~*ybv{o}CH2XG**K?BQO_5+S|S zBzTQ$xn1{-M}OQJoZOgEmZ?n6H|rNBFVUF^t<6!>%vG(iHneP>sl%m>gNr+<0$$9r zz8^m@+dp!C30Gf>t zBUKrnvP~fDPkj|2-nm~O>=@O>WL5jRn>&K+MMH=k#(C?svZbA%xxT$KR0{#ig4%;u zHFW5-TAxTndXEi`YS36TOo?|68+|36P+b>#q3oEqhwEGq5HMb1*#10Rm+2A8(o!7P zDBJMno~r<}aICxn4P|{?X3oUGBm?@cFC6Azn!VUr`sjYO*X*Or;EKxI?wV4|hu?(a zCH*8UYlr&=`zs8_b{t}Hg1OGD2y9;iB5ZH3Qh+Z#XJX;;mg@Q`^A*&nlwlvy-E)+aaC%eTJz3t!E5khX@KQyx6HEe=6Fq{d0s+ zF^FZZee7YwXN#y?G25hjQ%tEwR?`)2w@2i&uI0R7w`jO4ZNe* z1yMqpVxeg!{QrO;#P1`P?QbXid~Gav)azqxvip+h_&xgu0McaKDcOKXUlvwU zFoU18<94>j>)`U29=HfM19eCdZYZgt;i!5-(iKEuSc?!ozsVo6Qtj2_mhkEEK(SGp zMjMrZ;TZSEv@+tX{!@lY_kGv3ydM2R<$|8f@66M3-yepJPy&2+&C~sG9#~;%gLvY zVI~VGYP6hZ-iNH$g=GxEz0pYmgGoY+?F3*ue$WxdK9Jss$41z5Xt;KKRrVDQH#XC| z=v8>H!bq^s)Zy2DL?TA>ye&2YUdq|&=$q~)7?Re9y6fVN-bj0K%4x{i`@H-9SZ{=& zDbqKLq`&usH)AR&rM2k%ZpSN`p`_f~KQM9p(@RPa5lWhOZ?}vOx^zfCT~$kD83)RZ zrciZu4EMcwMu^fY(cI)Y^_!t;Pn!<=HLel(~M zW1_bD3FE|5>YgAXDGkK5cV;AMn|5XLRG=%7@@l6&UI0*23<@hz&9uHRi3jM%ESNcB zLZ$M2gG?yQqYzfIbXG!Q5mK-+Uz8DHhCA+lAxlPJV!3wjaACNz$yB{kKY74VHg&a- zx)9_Nih@mpm=trhoTo^r=Ret&XAGE222NT3{fa#ydwrEPCtH7OrFW@T;{3T{Up=vr z73)bN>Q_>cPkp`sZxME+yjYG_ASSfnp7_bj{YU7+OoOtW^XB`>4U=jZ(i`u>vGuTX zj@xgX16EzryHoAPFYY6MUxAc?${pUq6we*< z2U6wx9)U++p*DkyM!p1Wa?NWAW25(y2x#*|1HRC_Lz1t4v{+>@G}P0rcs3<_=G zdu@_e*axJ9b#E=*^GqXE>mrCOb~PV*wr%B>NUtg*02T7u-RB`SHCNiPrzzqtE5-AnaT z0P5X1LrG2TdbAJ)m>J!UD7vX)gATxzxVpNA#a}-R43Y>{O?i3w-GhUQvNCXgKNh>= z$0jEwnXhBSJW>Occ8>V`l$6=6nZ~vU7`P&#OcG*_SMLbY>$Gqx%BZL){J>_pOi41% z*Xp}2b=lef90CUJaH)8Xh-U-y`S8vRd5LrWC+w2#3_j!-nq&PS@ zCZS95|H#*0hYO4p)@9yXzo*X+ACT*2(XSYzI0GWsZM?lxjFN$nTvG6{6iZ z>?6rn=S=U1KEAbZ51012N--%7jYMXjg1kHv3k$GW)xWOv ze={a#x+|TZmj}F@c@Mv#aS_43e*Fskbz}7@u0o_YW0Iz8(g`5IJl=z&5pvk?%(np> zFj|djrjd`=UsWFVm@_=l<9G#VNQl|2Un1M=uZ?VaUYr12MMy~4)_whIRfJ#-Cj&{8 zVdrOhSsuW9*w;*elIJ#wUnj%@);uSBbab>DXwu^1;&yj;K>!Sf4RGuFOBnngeucx7 zzg`#Zb`baZUq*JId%#!F7F{b=JR>0?K?@kmpPiin{OgT=baVt-q?VO2|HoB)BXirA z`ap^HEHaVe5p%_yy_iHC92_EU7x}(Y6Upn_>Z4;uX%`8Pjy{_8r_)4`h=iityXUkv zOy3o9H3m%6N@0|DBLOH#{Ptz>N7jqt{2+0^qezF+TRE!JNP&|jBM z8@~L9A_(Q$z2Qxz^uNEASmBs+ASkS`wiGIsyZZ94Sl3#R#~78P$T;e9@s+x{U9+YZ9??aRitwK8SI69|n=#AVGQc*d z3bv@9t8bt6>m322K%erN*Yff6%%uEW2M`aS_CGv7XecmI1ts|@7=I#JN|J}IG+&11 z9=}%}IoS(|N{R$${>;8QATi9&o^%+}m^xi#_1w$R%35VoP;&nV(;RkjQg|6+&P`xw z%Eq~C8EnTAYppHsahNx!a2Zh&MDJ!{K9xD(L#78AbO7Errq0)=Ky3jA_SNkCDlhid z3p`BCTIX$lx_Y)3FP?ZigYpDVU_4HvT$of}@8R<2f3ng^6Q;TOF%8<585jz@T>T8i zPR@#v?qUWy8~1%jzHAb0H8>>|xqjuP?l=#$NO#PU0oj`dnTN4QXcvx8vQ3BL=)5UA zB{tU%2AR=NAhmC;&83lbeu`fg(~5O+g&lCQKkXO0nu3bm`$Wauf zy4$%UBl`(_7Xvy(<1ZSt9gpEP@Y6pGCU$DAEU8b1F61zg1FN7%TAG}OjQ9;_%f-H| zv}`WOqxdLC0;%e!9JzqAw8owyx% zC+hToRr1GR!=n3#za-CxR#}pnvE`_XR}%$;>=se`(w@tm+qXBW;k3XAis>;mH8n5@ zF)LEePq1^i1%2#Dt0wN#)HFg&WVx}tSIw1-7F-&D6+WSPG+eduhg0kNz0JIp*4HIz zBjVW^@8>@dD85H8PVt$4{W>UsQ487TR2>%WbKU?o9~s)vh~sSJv7I#VH{9U(**^)C z1Ohb=n1mJb>^-{KWSAum1^lv2Z!~^8qu{JNw=U?Q^Hx@f85><6aZQ<6Kn23yYMdx^ z{?Ih=MmQ0hSNHSGZ~LOfZ#>>_Pe(MX@fuz$pP6+yQQg11l300noeu%rJr(2M#b7}pe2(=hpw zQ*COq&y*1g60S~Kb3Jz43Qmg`d#N3gg9i;I2eO9MBS}LJ`zN|BLJE0CU!%ev4e4RW z){HAPbhQP%~iTsOhdQOGcs=;QM0{o_1{n^`5k3BsK zIxZGl_CNrB2JW+)dB26|J%xx;*C%gMA;x90c&2JULd6uNh5-?NOyu?tZXY3|?M4c>n!jY}1S72ZAYJHkA%n zN`~4Ru^s!q<3}dTjtM*-c9zVr_%3D*omWxfFbUW?oY#KcW~~gQzpaTjkC~+S*$B>? z=sX}DJD5^jA^*5Bphg4$D>pY6?2+y5?Y_hwhi3;C60;cmncUi>I26hJzKU^; zF)s3C2uC<2%8Am|%~r(5F=j$OJobE`OUqe4X^g@*Vi~BAnQBagd(R|b7EjtF5=P=mo68&_wNV*uR-{S0la_Nk5TE2 z8gIb;FKpFRn6m3VD@Sw~o13Tphtm22IwJq^i)ipTZg2IFqQ%S+ zaUf4iAL$G+E*-*lwitp|Na66W{fj~xB8a>_`8GqCh30e;lNw|)!}RhLOZbpy>_4B+ zg;7fg)uHPG#R9h(N>JR&h(n0ey^SaS?c-G^{;>XTDN)EE|^V?YX@4zYrot-F;EyFPvFQp8iH33CjQvFg2ojTK)>zw4Mb2x zAZZDZcEDq;29LA$2x?CN?orXuc=w0(E-@$oq!$W(8QBETcmI1z{cv!_)XAZ&W|p^U zue(8WsO+3H|4K?y$vvTdYXS5?0u45^8X6iv=(xHKW<2Pi1LlWX-e5GNQB2q3_wU~U zNG5HHd-I!0@1c&>_uTEw=G`>Qri|5yi<&`umPllkQ#TAmLJ6U&jJd%ArR3@9<(^@AppT-V_6$+NSbbZY;5OA9}4Pr0mvVy&|sFOWm2 zsi5WdC```F^6b)ZQnxz?d^?X_EflcHooh@Dbn>pHMVWSN`#mXSMU-q$*)!D zs0v>URQ6BKTr0(pYVx@C^{`tM6Wq%Itjo(KK9gc?{@|1AlVKQ7P0f^Ev6EV_N;c`ol1^W`JJ z==hy~N(%<0!dLmK6&FfR&=>)e|IqES9^tu0wLL&(VBCSAk#oqQ=I1KM5Yse3KM5NF z*`vAUvFP8|BZA}MMAp9J^;?rMK>$O zKxxg2?8&DVVjlZyvtjBe&5=)>K@&Ajyceg4ZF8x5@&eA~*Cogh(WovO4b9JymJ)WV zAZ@wU_xe@D!WJ_c6P`W(hDz_yI*;cnV)a59p@x4_!|8jT+A33+CN-=E}~NtY(RM<(}Vxtt^2#W8JS0v=wXr2N9-5^@MRn4ADsG zRSnT)o$)kvYfi zKZH2)B69kgU|2RP4kR>t$M187H0m|$_^hND$JPu*FdAv6qR zwdytrgQZjU3_GrbIO3Sf#})!-zyA_vX5U3zZL@e}w^&R-U-SC=GyrH5?)b*Ua!k-V8Gk4C`7hc(>%pU4-_(c9o|cZD!8Hvn@!X7EhODj= zZ|?@7c%yl!I@x=k%@&_NV(cU55_4%@aGVS!jeEq>z>2rkp`%j7-U(iv9g63|K-iA{ zJ=!F=OG>PwSrj(c8oka1t*xqX9bQ6}V7unynE%cW%(sG$FJJmrKsQg&4vijIL4n-K zn)Jt+?KZNe5feu_8OviOR=UTY#n~n&QVy0XYVsUbLNQ(8VJ11xVevDi;?9@SN?bsP z3ZZ22NNF#c8+pPChcNp^IE1Sm(iVUMStykcS%<+>r_uEVx}t)G@lU67`<9p*9Q=Ue z?Im2SrTMO|V$RO=4is@5Ju|t63=>?K1C53XQ-!fllc}iFDA0SSr>iyErscR>ue7HG zJa<*C25L;My?ZB>1w|e|>0nf?<;oK5C2`pJIL**Yt$#uNv8jwqkHh4p%@jDM2kq_3 zYFj%yPXYBn?0Ocz=_af&Fr?*KS5&kOh%lh1mEt`sZPPckusG|o@(3G`ySw{;RYjml zI^$ddFZ^Q_SFUgDx60po6acjjj4|^C=b+E*r0<5k;iz83s)bapV(Kc$6r?^@?~gZu zQMalV8J_o??ag)adS;&m^`5T9F*Qi>fOSzh2pO^}SpkwHEAj6i_^QaHygQrhF6V>% z2ysWHezs^)TOlr27S<9=qo}v0u9xTeFS3b5y(`%S{Kpx`-^1``>}~i)r|7h;<5)QF zlMR=nv-38>WqS@FuF!4Nehx%{$L11dW^!7^@7%uqr+^|2xYAsg^iY`o7dphTEbeX& zCB??U0sUiHuj#Tku}xhAJAYO}jbrvfhfvm$D_ey(vB;di#S)<9j3o-^6j$Whbs-t~ z*Iy15|7#hX3#FbY*WuwRBSp+u%pIXXt1Qig==BeEmvYDksf2ywzkgvQ@|BFSu}|e6dYz)D?pbJCs-+xg)ljMcFCN2$D+QY+A)`K3wXhtP2b`D3E#5` znu_};ZfkF?{7V9{AWw--8ZRihp zt)F30h>Oc|mc0wB&F*)pm9W~k7cLn~z3PwSmkB1G*#8-d^w#_>4gMIi>&JqZp%Nn^ zG#|4@3HB6gv)JJ7@e>V`eokRDrbBx!9SQ{@VS6FdWr0ZeB=|RxKfQcnZ)UGW(q$Z! zu#%9l;c6RNYGC4{R7clKk%VP+;-s)$-8RToxXD)tUlY|V;WuzN3I z<;zsLb?59C973CpB~kb;LcVKu!LcPgRIct`qIvei;}WPiW8P-vZdb1hh)JF+D)Ipe zAJnzQ)N|*I1Qm!=bRXPiIWJq3)owIBINgQ?+K_hzCr}?Z-oc&7O+UYYAo zi7s7f06M=hdqf1m(K#;7+ZxA+OyVr~;|fzg%h}Cxr&ufD4e;~M8XiC*=5a}yyT5fLig)?zG{pSmz5C+|)zW2hsRX>Wj zAg?gU_&+2b1m7Q}W!**g`WzoyXd%2|M67{49-;QhZN=QF(VJ6mJ!XfnD$#v-x<-bz zp|ARMer??Q-kwGf6?qc@Vi^;f=;=mpeHMQmBm!3%<=oszT(oC0p~~H`qgVXME&k7! zjI6>HV@F&3>~wF8JrW6tgH5q=)G<_4HI9y0IaO9xi`}pcE_gy6nexR#P^4^+TjPc! z#T@4t7uUk<4!CEDr1J9pK-Nj+)}8s9P|~&~1fupO@(lFb65_~tg9(2N=madGIoD3wgE9-%!Bo zsLE8+)RelpXxggg5BS<$JGlVDo&qbpv9s}*^VnR_Y_7p{xr1KV{m?*dD_mXjRt1$` zC@H@T1AptC7F7#L7Uy;+I=V_V$5?7xEEH&8m1T1m27ki2q{tSQpbR5z+D4^AGrQkY z@BTz{hZ@VlpGSq=*J(>6qz&&#++>muPa)osQ<|z4t9W#+ej*=wF!*mbtACp-%J}g0 zwqOXGoOjoXLp3{Hhwy5@94+l3rg0L%pKpU6*&fj}Fcz5wMA4}>3uTPc?hm3c(08{^ zp+EZ8Nr^Mn+-S`c6#O#_j}`YcI(6n+*akd`K=DTMoV6W~=CJywFGJ7to-&&*?Cxyk zd(?PEM&Xi|?TU{ZJMkeyZjBU~b;$_TnF@=TdaK%$bvzU8U7;3GQ0oJ4!tTR%Ww{@b zUfy`AE|bYXDlp{&&l^LjKWOi;_GkdF@Rvc#J)uB;kvk8_Glg=P+lQU?M)udDhcYu- z$Yb?NITSRDRI*Y|XfVIYz0I~y61)w06`HmmIrCk@gvx~8G_Y4YptW0~AK%adB#o~R zouXn@&ClW)pl9ptax?fup6M$m!h zxkYee(|btip zr?0@zka?>_^HiFxMVtIwJBVQjv8wotl}rAHl9JNc($Y}Hv8ou1lCv{qL^~Pq4nP{m zR879`^jE?eEf-r!8nlsg1xd#WD=koLy>*KRco&QqC4%_Q3Yhkem~U)uYB^gteZ26( z7Az_+cLY)N$B!SC^3_#DDZ!%SiwQU=bltxx^l@J5oCQIEI6+AdW0ktc*mh=uizvGH z#VPCpRGC~*B7X-~9R%&UY(Zug7JBQGe}RAx4082MQssjhAUG;0eF2k(M((C?L| z&^EW&%N77>b8~ah)%HWn`q~wJiCx%tQrU_?OU zSadWEb#-9mw|5K&rr?3^ov-m27&vU*0jzN1OU*tJbiUyn-r(co!_Vs?D%$?_D^m6~ zWee{2g&H9Zo#V#13OMBC7}?pgdW@MK2l6K)8~h3A#!&mEZNNtY!iA28h9>;?g-G5_ z?W)P<4ABpWxbTK~tf${l`Y|&z6^89W|JmLdl}nmWL{K&e2p4iP?LZfR^> z37<9ib@S^>j+4rt1m@xcN{M4Kc_s&t%g@E%?Zzr&U-Hq7mwottR~gsh^E5* zF>g}cT%kFs^#8m`0PL3PjbI7DzRwfrNyI*0p=WSYIu*qz?Sg`Wpz77a%&cbJ85qI? zy*H?U-8eXLS|2R~S5{1UaO$g6ar0EPEbSbUis;s!@>`m0mX#fhZaC>4n2ZZ{IL(7k2jvR$B<`X#@$QoaqxY-%90mZBdxwjqDQn8_ z`FUQfa;Q!*S|U0LFY*znz&kPj%NOUfy&>GgEnrouK|2IQ7C3v;zm{rk1C?K^gUev< zu8TVqdK5veWJztjI6vPxzP`My+?*>Jw~13gTz5& zj)k0#aq$i;_o4!g7OKn(nI92mY+%znD$UP%LhT4kjgHi53HR?3{WvcBdFy;>2*9Gz zq>L44v%8_I;p$@n2@C4EnGSzU&q~gVsf!w$pu>_b);CMgpgElLWqy@|E1fe~N=_^W zYQr~y)cLH%^R(rXs<*D0@I30!vgG6}@v5yIn6HtgUU69Iq3Bk*-J;Gy;X3PPRhT4> zynWQf$tn2a`BaZp$$d_BA}!Yf3+r)%pV^dtql)43YEym8+D;7hC0&gGLD7-0Sc|D8 z=A|2bZ#!I#^}Q+M7aa7&n-bgBPddQYsMhV`bB<9feM_Y&nMOFK)2=w|>*tO|-Qa{G zE4 zu%FPL`_({H)so@MpJQ()vAoemp7JCnr5SjC+SeQ_+xR%7IqIBlcWOVE)Ya5Y|D`P{ zWuX|7!&ylEp?BGvb1*HMoB8zqPNl9Ebc|= zt~%s!zWTb!C+!`b)#+O7Ml*h0u#tcaqtk2a&HU{sf6;Uf`{kcNRdgu_I$^z5hyf(p zn{5Jp_(}!~@`^Ufm;O$Te*`HNk0}0d;K%;fFHKw`nX!msw=_xag;_7&x3^pD@Jr~4 z-3PW61g5%+``Kw@?F&8l#Qpm2I2vF@pr@A5YIE=P9=X+D%76%3>bAb$gW&z%T=}&f zu)=}C6p%oJsbg-w24vZrjx|8{*7!Ntcdz1LB%37`Q@4~}XfHo+r6Qj*Ltc~}@+vhZ zbCu?Q0lqdMn?RI%ysXe5#2Yx)KXzJ#l*yH zY*^N5Hh5lm*&N@aW*=dY4XZLG<9@N|w%M0+zvfU_SO!aCs&O-5Y7=c!^;(gJ zgrqDK{td4zV5an8wn0Gob3C8BPAF&vp`oF`a_Hi8i5Jc3DH0O8q-q`x$RAp3iLh!a zV6xp9HaB!B?pAFtPXq^}I0a{6NcD3;I7C3@`rsgSkB z`7=AggZKQ~?bHP??&}pPf4{`6-oCO~KY$~UH%6Yc59j6P_vQ|cs^(XB;l5IFa>S9_ zj3hwB-*3>+Ax(P-bX)?YH=p=A{8b(WHd|+Iy#YePFXX?T1Q*h80Twv%7T+(G7Pt=Q z<}X7d@GoU_5H!wJ@Y2F0Ki=Pn%-2G6Y(|(e`=Mt(%(rPIv$NpeyO;iKuaV&|M{{ri z(wl{{S(J7lm1@G(I=z$t9v&WY!a&dEzXX3SE-uTMYL%P3VF$|5BWX%!n>WT#RTuaz zZCu>sXeH6pj_5QLI~X>eF1jiObA@OX(o5vXH5@js$B_MqemB%ef1kq7KaP$pRr7Ra zKl9uWQ&569E1R~vTSC436d3}6{+<{90=}GY)qq9P`b14dUfz1X5$bILD70z_j%uTL z(7wJ6cIc=U3K5LC1zcM(*MhvdA;$*H8mT#2-Fl}c7q{Ffy*dJjw;F#O`+c-wA5a~p zRi$1|PGzdU<>9UgasJ0Ql>krxU>hK46?4jxlBT;$q_4M?BL-I0a4TU8d%o*D7 zWJDv^T8|!(tN*cAqu*#r^n4CDSlYs~8YkGX^IP=dK>~%ys3h5TJ&BkGkBO?1{@ek| zNnRKC;Z<_)a9r}p1&UQBzaEiA<2nQ5aWE5_&O>4K>r@?DVF`F`&PN4w`>bWbx4v&s zicA!;Na7~%7M{L`r#eL4HpB;_n~tm&)=X@JmSso@C9`f4`QWz9S zNoPeoh^@)`rWP{{&E4vBWB7-5*eYoX($>cwFqd z88Bp9%T=>8MrJHv&UJU7atBeNLFS{E#PDGbMtNc%#9r7w_guI2v|8GAbFFEy8>E<2 zlxB%3eIMH^-ov2^Ni434?LHW$nD|H~qXNgkLaBluaWv8+y|MlHRD~); zDl+qIMR~04-dW@~s)`mPCmZiiH9=y?SstX+Bvd<%bYpNjw5HGf3bB1Lqf36gV{SLV zGK7JN2{g)NA_!ce7NLwko5s5bXQsb(!y7d$NB~VCLe+DI18+Lc4@ss9S{PcOSjv^E zbuK>{UEtw=y;8oG5G2EgE>>0ZPH41Np*%tB_{FODY;^j^=Z?5X zW20Pn&-)|IyMn|%a48K94l?M!FhyZaSF3Km$=9ip7#{w3!qH)?oy>n4mo?mA*Fg=c z*-9;1XZx*~h1bO1+E4GOv&<~RJiy|+U>{%`$};M~J;op#oZq%<+0&_$DXFL2>m9N5 zO93CMk-Hh%VbI+AA%ySb>ai;_r^{9?1B0(Of=SrR_?NP1>xSG)qIM@inSPK1kcwmb zR{R`$O{>P`OT=#V?lR`m^LKi*v0>ac^-+;iZaX{;&PJKYJ`0@37Lhu>9dl-zWvD?l z_fGR*wp)OBVRfFn1$DSYl1vN|m-=U^m2ZpuZ&4Z1{y!xk%LTI_N z1-v7xjuX$j5Vh#bJ;#u2m2({50YLD#wfEB&95RV;kfMTahSf#iY4Pkt!!@v(DrYZMG!nw!7X_#1PSmX#6mxUtoKq=}no z5)H*7PIsUOb6z}6NQlM|TF}=8RpF7%Oc<%sg*2OYf~d}n?T_7s zF!+gn=y7=Pyi~)X)fun5W&0t=z;G)~)yEW4kx+VBxDFft2f(2oOLjJ|>kIPv1@#2q zAGr&`5{ynMOBL9EKmW6bq1M7Ee~ew@VUUI%m&4lXe5F5n3TtOylw0}fuh>zsQbAgJ zV`IYuh@juq6x8jHhL8wX*VHtA?yUovihUln0Yk>Qz3tjUGqdA7co0>DtR!;Jm-%}3 zs4Txw`{Q=$fkCDq++*Q*Q|$O?^R?9qDKEG!0eh}Om z>ISC&yse7Z(2o=fO`uFxRNNn%I(MYX=`c|hYNL#al)=LOKq4aR+F?DD0a{imx5SB( z5hmiXbLcy<*SSv&e#c;JIb!QhZ1~1i;>#c?gK|p(Sti@KLFMyHH- zds}9RP<@7xmz!RTX0g`LadY`xk3y?Z^jU+-`F`W(rWMqf?-GkuoAD$URaPJ}bKVTGWP*z}MALSU>LbC2{2oVj3=K~bs<@cgHezVH|BYY9Qz8%J z){N9;Fg{Ir!L-O@o2?gQ(@_0WNzH0R{~)1)=}X zY)9^jkBY5;pO5X`VU6Kb69!o$bbi&?JEyguD!%3RWjSkpF0J-Crnn1g}Un(dBcx zcI^PwX6sSTm|-8n#uxrIfal{NI2cs+2l*+6pvdtL z)jY=@5Emfbvl*Le%wnpxHn{x6t*>h06k2Z-_)-m+{2k$JUlA zAVZNNzf>~m*$;2T?NEl>+n5|*uIEM;FY2mahwcK4DyDIj>kGaLpx!cYPO>J@QjbX< z$U3dnCUnxw-BkY$NBT8srg11K8*ikSL6gd$PkvvD#P#{-b(7)CkNcmIz^_k0(&hsp z#FJ<<%xo=6g)Hp9!jHdiL0d5FDx`V7N8<^KwSa9X$jkyKQ5`&T>%uQzmNzfXH;HQ? z5J)mG6@B{$G(k(9+_Wrau2OLP@XTmOSK^_Zj<0EKT zzMI?3Gpr__Te|WonhSJ*#;k8Qu{sv|e^$Cu-Iy?}N@ygJn#T`#7~p>v>#pX)A$%t0 z`q(M`qx55m(R#}q$`AezFub__KvJao2QX;=i_Qd(MAh`n35xwIVkn;jg1@4R7t^(D4n}U<~AUm8jms1W2JVC?o_4@d%Jh2 zOxNPV&W~K-&1Q#3REUc9e2?AxiPZIjdIO&9Ed&21+vT5-oB>s7=@*DfAm|5WK`wPO zqH772++1@DXI}bFMP8J*9`xF-Zg-gojufH1chl~7D6KadUxav{E)L`oC$1TniQlGm zMQpaCdD=|0ZSfArXAV#zLoVQV4BpCJ>~=rm3->5$m_MwVq`CF+V^K8~?m<)ZM*iC@ z*FenS%3hrb)z8jqeC#};YGqAv=&5p4^CXy^xJK2&pk6rcgLq2 z<_T?|_rMz!Ss`h)FN&V?%4Es}NHPe+X$0o-*%Ji*8A2cmkPYj2x;yT9%{vy&2C@y% zMVda9_x@BpH#E3F(b9~sF1cAmBH{fhZck(cjwx@N-neLKS~yIu?v4IFl$Hu6Dju|h z;O~ey4_G@~Y_9KtoGc0t#xUyMpy!2N0^}FVsAr0YpiDjM5`u@>>%d}(U zwrxC<;*}j@wmiUE`cZfKYGV^kt8$3V_K_g6$$I?rHZ@G*bixw)Z)(buQ2X~JM1Mk;A7hgT;x<4W0iw_j@vRR*?o z1RQ;1gkP+`6MO5naZK>1bApyLXUL*hpH2PYq3+hS5wWIpHdgQ^?K2wKhB>|^+eETF z6*2_A6INn}N!#zlp79yWt}|6?-u--Aka%fII#TC_kehpH^wODN`pWGv7WAc4*7c}W zPQ5u2>g+)nfqh?O?lN2BN=s03ee2qNg9I|lw+^Ix=d|YRJt%6fseIosjiWa3$Wvy(Xq#D&c z)#*=k7HJ;fIwc$EfB(iYUSHk(?RA|haWbj*|CK=18+7vm&9^q!h2n_y75DFcUi7ak7pdrI1FLOh z+ZS!h2CaFvsm^H>GK=njy78afCJywp;XSvpx8I$g*RMpVQikyfb{Gf@t|(33O=04g z31X(%arl5K$Eswc1{4I%g3Tc^@&X;L-=bI&*rupO`Z^NJOq+s2!*|nO=Lzw(Awymz ze|pG|7aWZK6gg!K0P_z|lNT7?DJBn4CgyZb%0**WYKU}5+#Z+d4EcDuOPKnucZ&rs;tWWoTBgj2`#8>G|qf0 zDHs=rVb^vWh8L7V$^ZJSO|b%Q*cHF@{$<5N^v#(BT;V&!956Z$o$Dq&NMEzdk8zZQ zgoS~(AIn&+Qa(Z0gF(6vA~wfg^8->abnOSJ=pf#>uOj$~*oa)s5I6a-0GoWe-)^_X z;P=!f13A_%#OBX#O+wlZF?37&#Mfd>M7(Azk8Fnt)@mCFBw3dXj$X&Rv^U-IG&EZ# z_>;&7VdLg4*;H9I9UP2cv{Vcw)tk4U(tjVSXclhw!-i8u=2MDZ1}`1x6wsrZskczR zepS>9GRlDiGSZV(c1E_g#hL|DQc_bO7c3_iHn#r2N%r7t%e_F0RH+D~v}U-3%Rt{) z@4_Wcy$R9(u}Z7bK;Hf($luS|*6g@*ui*jf(%k#5TOVEW7|3N)6(#8?=vsp`%z_wJ z6*xs@N&5YAGzOcR?&3Xm8qrX_$6e=VCnQgw#z`&>;j%Djp3lGk|7O?w>Y4hX z-$(uTy}J`QDQKHr<7e*owN+EM{^V3#uJYdH2Tw=mvqAnbI` zjDPPJm%N1E>r3bE);2N|SMl?!w70(tEZBDzpMQOOnWMb^8y#O$$tyDYJbhNtx}Ucz zE!5~*CjNi7_`=Y)Re8c|fjO1SZ0XZ{lk#nSF?lZ(Teg_-|EN^VZ;o6Z{Be&#W-0Gi ze<3Hm_!l>~m}Vbe=XCG+_LBZ;2|a;Vowm|FYPk!P_Wo`S3KY1#jyE>@Rran6llLFo zlY6|XHOS8L9k6G0>rU?U=hLQ4c~W2j+&v=(yBHLB9Hi<3$dZk{iz9Py81ii1A>He? z`0&FS|94&Z1srnJm;N=&dhJ8Ml+x;NPtQJob?ca$)0dzBUWM^0r zxh3lDBH*@J1~I2yU-v3$_3FjU1Qm5QAHv*EbI-`^oU7yjZ3MTbS#&KrlU5AuPl2>T z!H#<1-~xBU?N4 literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-sql.png b/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-sql.png new file mode 100644 index 0000000000000000000000000000000000000000..45e0dd6e49d5b038519f64a546503b1135a3eaa2 GIT binary patch literal 103255 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

)hRb)3D#V1#%SH|7 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

W)KbdQG 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 R;rBye`npD!%P##L`G2iSDlq^6 literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-timeseries.png b/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-querybuilder-timeseries.png new file mode 100644 index 0000000000000000000000000000000000000000..c8a7e2c7b7fa3241457b929db930411e97cade6f GIT binary patch literal 75893 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%0AnGoYt{t{L6nTv=(ch9qi1_BF+>~%a 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™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 literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-variables.png b/public/app/plugins/datasource/grafadruid-druid-datasource/img/screenshot-variables.png new file mode 100644 index 0000000000000000000000000000000000000000..f8a47bfe3360436626f2d8a8e804f4024d6c6d67 GIT binary patch literal 58781 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 + .setConfigEditor(ConfigEditor) + .setQueryEditor(QueryEditor) + .setVariableQueryEditor(VariableQueryEditor); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/plugin.json b/public/app/plugins/datasource/grafadruid-druid-datasource/plugin.json new file mode 100644 index 0000000000000..cdfb2a950c26e --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/plugin.json @@ -0,0 +1,51 @@ +{ + "type": "datasource", + "name": "Druid", + "id": "grafadruid-druid-datasource", + "metrics": true, + "backend": true, + "alerting": true, + "logs": true, + "executable": "grafadruid-druid-datasource", + "info": { + "description": "Connects Grafana to Druid", + "author": { + "name": "Grafadruid" + }, + "keywords": ["druid"], + "logos": { + "small": "img/druid.svg", + "large": "img/druid.svg" + }, + "links": [ + { + "name": "Website", + "url": "https://github.com/grafadruid/druid-grafana" + }, + { + "name": "License", + "url": "https://github.com/grafadruid/druid-grafana/blob/master/LICENSE" + } + ], + "screenshots": [ + { "name": "datasource - connection", "path": "img/screenshot-datasource-connection.png" }, + { "name": "datasource - default settings", "path": "img/screenshot-datasource-default-settings.png" }, + { "name": "panels", "path": "img/screenshot-panels.png" }, + { "name": "query builder - json", "path": "img/screenshot-querybuilder-json.png" }, + { "name": "query builder - sql", "path": "img/screenshot-querybuilder-sql.png" }, + { "name": "query builder - timeseries", "path": "img/screenshot-querybuilder-timeseries.png" }, + { "name": "query builder - settings", "path": "img/screenshot-querybuilder-settings.png" }, + { "name": "variables", "path": "img/screenshot-variables.png" }, + { "name": "variables - formatter - druid:json", "path": "img/screenshot-querybuilder-formatter-druidjson.png" }, + { "name": "explore - logs", "path": "img/screenshot-explore-logs.png" }, + { "name": "query builder - settings - logs", "path": "img/screenshot-querybuilder-settings-logs.png" } + ], + "version": "%VERSION%", + "updated": "%TODAY%" + }, + "dependencies": { + "grafanaDependency": ">=7.0.0", + "grafanaVersion": "7.x.x", + "plugins": [] + } +} diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/types.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/types.ts new file mode 100644 index 0000000000000..b5e8da9cc8c46 --- /dev/null +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/types.ts @@ -0,0 +1,17 @@ +import { DataQuery, DataSourceJsonData } from '@grafana/data'; +import { QuerySettings } from './configuration/QuerySettings/types'; +import { ConnectionSettings } from './configuration/ConnectionSettings/types'; + +//expr is a workaround: https://github.com/grafana/grafana/issues/30013 +export interface DruidQuery extends DataQuery { + builder: any; + settings: QuerySettings; + expr: string; +} + +export interface DruidSettings extends DataSourceJsonData { + connection?: ConnectionSettings; + query?: QuerySettings; +} + +export interface DruidSecureSettings {} diff --git a/public/app/plugins/panel/img/logo.svg b/public/app/plugins/panel/img/logo.svg new file mode 100644 index 0000000000000..2d41fa5441e64 --- /dev/null +++ b/public/app/plugins/panel/img/logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/.gitignore b/public/app/plugins/panel/sankey-panel-0.5.0/.gitignore new file mode 100644 index 0000000000000..521bf24711e65 --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/.gitignore @@ -0,0 +1,31 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +node_modules/ + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Compiled binary addons (https://nodejs.org/api/addons.html) +dist/ +artifacts/ +work/ +ci/ +e2e-results/ + +# Editors +.idea + diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/.prettierignore b/public/app/plugins/panel/sankey-panel-0.5.0/.prettierignore new file mode 100644 index 0000000000000..16c7d95a61e3b --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/.prettierignore @@ -0,0 +1,3 @@ +src/Error.tsx +src/Sankey.js +src/SankeyPanel.tsx \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/LICENSE b/public/app/plugins/panel/sankey-panel-0.5.0/LICENSE new file mode 100644 index 0000000000000..f882365155a8a --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Ismael + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/README.md b/public/app/plugins/panel/sankey-panel-0.5.0/README.md new file mode 100644 index 0000000000000..ee7c9c4877838 --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/README.md @@ -0,0 +1,82 @@ +# Grafana Sankey Panel + +Sankey diagram implementation for directed flow visualization between nodes in an acyclic network. + +![sankey-panel](img/sankey-panel.png) + +## Installing + +Using the grafana-cli: + +```bash +grafana-cli --pluginUrl https://github.com/IsmaelMasharo/sankey-panel/raw/master/sankey-panel.zip plugins install sankey-panel +``` + +## Grafana Version + +Tested on Grafana 7.3.1 + +## Required Fields + +The diagram gets constructed from a data source **formatted as table** with 3 mandatory fields: **source** (text), **target** (text), **value** (numeric, no nulls). The diagram at the beginning was created with the following table format: + +| source | target | value | +|----------|----------|---------| +| A | D | 2 | +| B | D | 2 | +| B | E | 2 | +| A | F | 2 | +| D | E | 2 | +| D | F | 3 | +| E | F | 4 | +| C | D | 1 | +| C | E | 1 | +| E | G | 1 | + +Being an acyclic implementation of the Sankey diagram **loops are not allowed**: + +| source | target | value | +|----------|----------|---------| +| A | B | 2 | +| B | A (*x*) | 2 | + +To avoid *circular link error* [a masked prefix](https://github.com/IsmaelMasharo/sankey-panel/issues/1#issuecomment-757972917) could be set on the target values: + +| source | target | value | +|----------|----------|---------| +| A | B | 2 | +| B | P-A | 2 | + +## Display Options + +There are 5 options for displaying the diagram: *Alignment*, *Color*, *Edge Color*, *Display Values*, *Highlight Connections* + +### Alignment + +Arranges the nodes to one of the following sides: Left, Right, Center, Justify. See d3 [sankey nodeAlign](https://github.com/d3/d3-sankey#alignments) for image reference. + +### Color + +Nodes and links color. Based on d3 [categorical schemes](https://github.com/d3/d3-scale-chromatic#categorical). + +### Edge Color + +Represents the link's color transition from source to the target node. + +- Input: Link takes the color of the source node. +- Output: Link takes the color of the target node. +- Input-Output: The link will be colored as a gradient from source to target node colors. +- None: Gray links. + +### Display Values + +Values are shown next to the node name. + +- Total: Display link weight value. +- Percentage: Display link weight percentage value relative to the source. +- Both: Display both total and percentage. +- None: No values displayed (except for node name). + +### Highlight Connections + +Boolean. Highlights links and nodes with a direct connection to the hovered node. diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/img/logo.svg b/public/app/plugins/panel/sankey-panel-0.5.0/img/logo.svg new file mode 100644 index 0000000000000..2d41fa5441e64 --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/img/logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/logo.svg b/public/app/plugins/panel/sankey-panel-0.5.0/logo.svg new file mode 100644 index 0000000000000..2d41fa5441e64 --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/module.js b/public/app/plugins/panel/sankey-panel-0.5.0/module.js new file mode 100644 index 0000000000000..40c143eb0ffc3 --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/module.js @@ -0,0 +1,3 @@ +/*! For license information please see module.js.LICENSE.txt */ +define(["react","d3","@grafana/data","@grafana/ui"],(function(t,e,n,r){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=5)}([function(e,n){e.exports=t},function(t,n){t.exports=e},function(t,e){t.exports=n},function(t,e){t.exports=r},,function(t,e,n){"use strict";n.r(e);var r={};n.r(r),n.d(r,"sankey",(function(){return M})),n.d(r,"sankeyCenter",(function(){return v})),n.d(r,"sankeyLeft",(function(){return y})),n.d(r,"sankeyRight",(function(){return p})),n.d(r,"sankeyJustify",(function(){return _})),n.d(r,"sankeyLinkHorizontal",(function(){return F}));var o=n(2);var i=function(){return(i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=i.next()).done;)a.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a}var u=n(0),l=n.n(u),c=n(1);function f(t,e){let n=0;if(void 0===e)for(let e of t)(e=+e)&&(n+=e);else{let r=-1;for(let o of t)(o=+e(o,++r,t))&&(n+=o)}return n}function h(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n=e)&&(n=e);else{let r=-1;for(let o of t)null!=(o=e(o,++r,t))&&(n=o)&&(n=o)}return n}function d(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n>e||void 0===n&&e>=e)&&(n=e);else{let r=-1;for(let o of t)null!=(o=e(o,++r,t))&&(n>o||void 0===n&&o>=o)&&(n=o)}return n}function g(t){return t.target.depth}function y(t){return t.depth}function p(t,e){return e-1-t.height}function _(t,e){return t.sourceLinks.length?t.depth:e-1}function v(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?d(t.sourceLinks,g)-1:0}function k(t){return function(){return t}}function m(t,e){return x(t.source,e.source)||t.index-e.index}function b(t,e){return x(t.target,e.target)||t.index-e.index}function x(t,e){return t.y0-e.y0}function w(t){return t.value}function S(t){return t.index}function L(t){return t.nodes}function A(t){return t.links}function O(t,e){const n=t.get(e);if(!n)throw new Error("missing: "+e);return n}function j({nodes:t}){for(const e of t){let t=e.y0,n=t;for(const n of e.sourceLinks)n.y0=t+n.width/2,t+=n.width;for(const t of e.targetLinks)t.y1=n+t.width/2,n+=t.width}}function M(){let t,e,n,r=0,o=0,i=1,a=1,s=24,u=8,l=S,c=_,g=L,y=A,p=6;function v(){const t={nodes:g.apply(null,arguments),links:y.apply(null,arguments)};return M(t),T(t),P(t),C(t),V(t),j(t),t}function M({nodes:t,links:e}){for(const[e,n]of t.entries())n.index=e,n.sourceLinks=[],n.targetLinks=[];const r=new Map(t.map((e,n)=>[l(e,n,t),e]));for(const[t,n]of e.entries()){n.index=t;let{source:e,target:o}=n;"object"!=typeof e&&(e=n.source=O(r,e)),"object"!=typeof o&&(o=n.target=O(r,o)),e.sourceLinks.push(n),o.targetLinks.push(n)}if(null!=n)for(const{sourceLinks:e,targetLinks:r}of t)e.sort(n),r.sort(n)}function T({nodes:t}){for(const e of t)e.value=void 0===e.fixedValue?Math.max(f(e.sourceLinks,w),f(e.targetLinks,w)):e.fixedValue}function P({nodes:t}){const e=t.length;let n=new Set(t),r=new Set,o=0;for(;n.size;){for(const t of n){t.depth=o;for(const{target:e}of t.sourceLinks)r.add(e)}if(++o>e)throw new Error("circular link");n=r,r=new Set}}function C({nodes:t}){const e=t.length;let n=new Set(t),r=new Set,o=0;for(;n.size;){for(const t of n){t.height=o;for(const{source:e}of t.targetLinks)r.add(e)}if(++o>e)throw new Error("circular link");n=r,r=new Set}}function V(n){const l=function({nodes:t}){const n=h(t,t=>t.depth)+1,o=(i-r-s)/(n-1),a=new Array(n);for(const e of t){const t=Math.max(0,Math.min(n-1,Math.floor(c.call(null,e,n))));e.layer=t,e.x0=r+t*o,e.x1=e.x0+s,a[t]?a[t].push(e):a[t]=[e]}if(e)for(const t of a)t.sort(e);return a}(n);t=Math.min(u,(a-o)/(h(l,t=>t.length)-1)),function(e){const n=d(e,e=>(a-o-(e.length-1)*t)/f(e,w));for(const r of e){let e=o;for(const o of r){o.y0=e,o.y1=e+o.value*n,e=o.y1+t;for(const t of o.sourceLinks)t.width=t.value*n}e=(a-e+t)/(r.length+1);for(let t=0;t0))continue;let o=(e/r-t.y0)*n;t.y0+=o,t.y1+=o,G(t)}void 0===e&&i.sort(x),N(i,r)}}function B(t,n,r){for(let o=t.length-2;o>=0;--o){const i=t[o];for(const t of i){let e=0,r=0;for(const{target:n,value:o}of t.sourceLinks){let i=o*(n.layer-t.layer);e+=J(t,n)*i,r+=i}if(!(r>0))continue;let o=(e/r-t.y0)*n;t.y0+=o,t.y1+=o,G(t)}void 0===e&&i.sort(x),N(i,r)}}function N(e,n){const r=e.length>>1,i=e[r];z(e,i.y0-t,r-1,n),H(e,i.y1+t,r+1,n),z(e,a,e.length-1,n),H(e,o,0,n)}function H(e,n,r,o){for(;r1e-6&&(i.y0+=a,i.y1+=a),n=i.y1+t}}function z(e,n,r,o){for(;r>=0;--r){const i=e[r],a=(i.y1-n)*o;a>1e-6&&(i.y0-=a,i.y1-=a),n=i.y0-t}}function G({sourceLinks:t,targetLinks:e}){if(void 0===n){for(const{source:{sourceLinks:t}}of e)t.sort(b);for(const{target:{targetLinks:e}}of t)e.sort(m)}}function I(t){if(void 0===n)for(const{sourceLinks:e,targetLinks:n}of t)e.sort(b),n.sort(m)}function D(e,n){let r=e.y0-(e.sourceLinks.length-1)*t/2;for(const{target:o,width:i}of e.sourceLinks){if(o===n)break;r+=i+t}for(const{source:t,width:o}of n.targetLinks){if(t===e)break;r-=o}return r}function J(e,n){let r=n.y0-(n.targetLinks.length-1)*t/2;for(const{source:o,width:i}of n.targetLinks){if(o===e)break;r+=i+t}for(const{target:t,width:o}of e.sourceLinks){if(t===n)break;r-=o}return r}return v.update=function(t){return j(t),t},v.nodeId=function(t){return arguments.length?(l="function"==typeof t?t:k(t),v):l},v.nodeAlign=function(t){return arguments.length?(c="function"==typeof t?t:k(t),v):c},v.nodeSort=function(t){return arguments.length?(e=t,v):e},v.nodeWidth=function(t){return arguments.length?(s=+t,v):s},v.nodePadding=function(e){return arguments.length?(u=t=+e,v):u},v.nodes=function(t){return arguments.length?(g="function"==typeof t?t:k(t),v):g},v.links=function(t){return arguments.length?(y="function"==typeof t?t:k(t),v):y},v.linkSort=function(t){return arguments.length?(n=t,v):n},v.size=function(t){return arguments.length?(r=o=0,i=+t[0],a=+t[1],v):[i-r,a-o]},v.extent=function(t){return arguments.length?(r=+t[0][0],i=+t[1][0],o=+t[0][1],a=+t[1][1],v):[[r,o],[i,a]]},v.iterations=function(t){return arguments.length?(p=+t,v):p},v}var T=Math.PI,P=2*T,C=P-1e-6;function V(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function E(){return new V}V.prototype=E.prototype={constructor:V,moveTo:function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},quadraticCurveTo:function(t,e,n,r){this._+="Q"+ +t+","+ +e+","+(this._x1=+n)+","+(this._y1=+r)},bezierCurveTo:function(t,e,n,r,o,i){this._+="C"+ +t+","+ +e+","+ +n+","+ +r+","+(this._x1=+o)+","+(this._y1=+i)},arcTo:function(t,e,n,r,o){t=+t,e=+e,n=+n,r=+r,o=+o;var i=this._x1,a=this._y1,s=n-t,u=r-e,l=i-t,c=a-e,f=l*l+c*c;if(o<0)throw new Error("negative radius: "+o);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(f>1e-6)if(Math.abs(c*s-u*l)>1e-6&&o){var h=n-i,d=r-a,g=s*s+u*u,y=h*h+d*d,p=Math.sqrt(g),_=Math.sqrt(f),v=o*Math.tan((T-Math.acos((g+f-y)/(2*p*_)))/2),k=v/_,m=v/p;Math.abs(k-1)>1e-6&&(this._+="L"+(t+k*l)+","+(e+k*c)),this._+="A"+o+","+o+",0,0,"+ +(c*h>l*d)+","+(this._x1=t+m*s)+","+(this._y1=e+m*u)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,r,o,i){t=+t,e=+e,i=!!i;var a=(n=+n)*Math.cos(r),s=n*Math.sin(r),u=t+a,l=e+s,c=1^i,f=i?r-o:o-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+u+","+l:(Math.abs(this._x1-u)>1e-6||Math.abs(this._y1-l)>1e-6)&&(this._+="L"+u+","+l),n&&(f<0&&(f=f%P+P),f>C?this._+="A"+n+","+n+",0,1,"+c+","+(t-a)+","+(e-s)+"A"+n+","+n+",0,1,"+c+","+(this._x1=u)+","+(this._y1=l):f>1e-6&&(this._+="A"+n+","+n+",0,"+ +(f>=T)+","+c+","+(this._x1=t+n*Math.cos(o))+","+(this._y1=e+n*Math.sin(o))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var B=E,N=Array.prototype.slice,H=function(t){return function(){return t}};function z(t){return t[0]}function G(t){return t[1]}function I(t){return t.source}function D(t){return t.target}function J(t){var e=I,n=D,r=z,o=G,i=null;function a(){var a,s=N.call(arguments),u=e.apply(this,s),l=n.apply(this,s);if(i||(i=a=B()),t(i,+r.apply(this,(s[0]=u,s)),+o.apply(this,s),+r.apply(this,(s[0]=l,s)),+o.apply(this,s)),a)return i=null,a+""||null}return a.source=function(t){return arguments.length?(e=t,a):e},a.target=function(t){return arguments.length?(n=t,a):n},a.x=function(t){return arguments.length?(r="function"==typeof t?t:H(+t),a):r},a.y=function(t){return arguments.length?(o="function"==typeof t?t:H(+t),a):o},a.context=function(t){return arguments.length?(i=null==t?null:t,a):i},a}function R(t,e,n,r,o){t.moveTo(e,n),t.bezierCurveTo(e=(e+r)/2,n,e,o,r,o)}function W(t){return[t.source.x1,t.y0]}function q(t){return[t.target.x0,t.y1]}var F=function(){return J(R).source(W).target(q)};function U(t,e){for(var n=0;n0&&this._data.links.length>0}},{key:"_setLinkGradient",value:function(){var t=this,e=this._svgLink.append("linearGradient").attr("id",(function(t){return t.uid="link-".concat(t.index,"-").concat(Math.random())})).attr("gradientUnits","userSpaceOnUse").attr("x1",(function(t){return t.source.x1})).attr("x2",(function(t){return t.target.x0}));e.append("stop").attr("offset","0%").attr("stop-color",(function(e){return t._color(e.source)})),e.append("stop").attr("offset","100%").attr("stop-color",(function(e){return t._color(e.target)}))}},{key:"_setLinkStroke",value:function(t){switch(this._edgeColor){case X:return"#aaa";case Y:return"url(#".concat(t.uid,")");case $:return this._color(t.source);case tt:return this._color(t.target);default:return}}},{key:"_showLinks",value:function(t){var e=[];[{linkType:"sourceLinks",nodeType:"target"},{linkType:"targetLinks",nodeType:"source"}].forEach((function(n){t[n.linkType].forEach((function(t){e.push(t[n.nodeType])}))})),this._gBound.selectAll(".sankey-node").style("opacity",(function(n){return t.name===n.name||e.find((function(t){return t.name===n.name}))?"1":"0.2"})),this._gBound.selectAll(".sankey-link").style("opacity",(function(e){return!e||e.source.name!==t.name&&e.target.name!==t.name?"0.2":"1"}))}},{key:"_showAll",value:function(){this._gBound.selectAll(".sankey-node").style("opacity","1"),this._gBound.selectAll(".sankey-link").style("opacity","1")}},{key:"_formatValue",value:function(t){return c.format(".2~f")(t)}},{key:"_formatPercent",value:function(t){return c.format(".2~%")(t)}},{key:"_formatThousand",value:function(t){return c.format(".3~s")(t)}},{key:"_labelNode",value:function(t){var e=this._nodes.filter((function(e){return e.depth===t.depth})),n=c.sum(e,(function(t){return t.value})),r=this._formatThousand(t.value),o=this._formatPercent(t.value/n),i=t.name;switch(this._displayValues){case Z:i="".concat(i,"\n ").concat(r);break;case Q:i="".concat(i,"\n ").concat(o);break;case K:i="".concat(i,"\n ").concat(o," - ").concat(r)}return i}},{key:"_renderSVG",value:function(){var t=this;this._container.style("background-color",this._background),this._gBound=this._container.append("g").attr("transform","translate(".concat(this._marginLeft,", ").concat(this._marginTop,")")),this._svgNode=this._gBound.append("g").attr("stroke","#000").selectAll(".sankey-node").data(this._nodes,(function(t){return t.name})).join("rect").attr("class","sankey-node").attr("id",(function(t){return t.name})).attr("x",(function(t){return t.x0})).attr("y",(function(t){return t.y0})).attr("rx",2).attr("ry",2).attr("height",(function(t){return t.y1-t.y0})).attr("width",(function(t){return t.x1-t.x0})).attr("stroke",(function(e){var n=JSON.parse(t._colorArray);return Object.keys(n).includes(e.name)?n[e.name]:"rgba(148, 153, 168, 1)"})).attr("fill",(function(e){var n=JSON.parse(t._colorArray);return Object.keys(n).includes(e.name)?n[e.name]:"rgba(148, 153, 168, 1)"})).on("mouseover",(function(e){return t._highlightOnHover&&t._showLinks(e)})).on("mouseout",(function(e){return t._highlightOnHover&&t._showAll()})),this._svgLink=this._gBound.append("g").attr("fill","none").attr("stroke-opacity",.3).selectAll("g").data(this._links,(function(t){return"".concat(t.source.name,"-").concat(t.target.name)})).join("g").style("mix-blend-mode","multiply"),"path"===this._edgeColor&&this._setLinkGradient(),this._svgLink.append("path").attr("class","sankey-link").attr("d",F()).attr("stroke","rgba(182, 185, 196, 1)").attr("stroke-width",(function(t){return Math.max(1,t.width)})),this._gBound.append("g").attr("font-family","sans-serif").attr("font-size",10).selectAll("text").data(this._nodes).join("text").attr("x",(function(t){return t.x0+8})).attr("y",(function(t){return(t.y1+t.y0)/2})).attr("dy","0.35em").text((function(e){return t._labelNode(e)})),this._gBound.append("g").attr("font-family","sans-serif").attr("font-size",10).selectAll("text").data(this._nodes).join("text").attr("x",(function(t){return t.x0+8})).attr("font-size",14).attr("font-weight","700").attr("y",(function(t){return(t.y1+t.y0)/2+16})).attr("dy","0.35em").text((function(e){return t._formatValue(e.value)})),this._svgNode.append("title").text((function(e){return"".concat(e.name,"\n").concat(t._formatValue(e.value))})),this._svgLink.append("title").text((function(e){return"".concat(e.source.name," → ").concat(e.target.name,"\n").concat(t._formatValue(e.value))}))}},{key:"data",value:function(t){return arguments.length?(this._data=t,this):this._data}},{key:"width",value:function(t){return arguments.length?(this._width=+t,this):this._width}},{key:"height",value:function(t){return arguments.length?(this._height=+t,this):this._height}},{key:"align",value:function(t){return arguments.length?(this._sankeyAlignType=t,this):this._sankeyAlignType}},{key:"colorScheme",value:function(t){return arguments.length?(this._colorScheme=t,this):this._colorScheme}},{key:"colorArray",value:function(t){return arguments.length?(this._colorArray=t,this):this._colorArray}},{key:"edgeColor",value:function(t){return arguments.length?(this._edgeColor=t,this):this._edgeColor}},{key:"displayValues",value:function(t){return arguments.length?(this._displayValues=t,this):this._displayValues}},{key:"highlightOnHover",value:function(t){return arguments.length?(this._highlightOnHover=t,this):this._highlightOnHover}},{key:"render",value:function(){return this._validate()&&(this._init(),this._renderSVG()),this}}])&&U(e.prototype,n),o&&U(e,o),t}(),nt=n(3),rt=function(t){var e=t.message;return l.a.createElement("p",{style:ot},l.a.createElement("div",{style:it},l.a.createElement(nt.Icon,{name:"exclamation-triangle"}),l.a.createElement("div",{style:at},e)))},ot={height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},it={padding:"15px 20px",marginBottom:"4px",position:"relative",color:"rgb(255, 255, 255)",textShadow:"rgb(0 0 0 / 20%) 0px 1px 0px",borderRadius:"3px",display:"flex",flexDirection:"row",alignItems:"center",background:"linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))"},at={marginLeft:10},st=function(t){var e=t.options,n=t.data,r=t.width,o=t.height,i={source:"source",target:"target",value:"value"},a="Required fields not present: "+Object.keys(i).join(", "),f=s(Object(u.useState)({isError:!1,message:""}),2),h=f[0],d=f[1],g=s(Object(u.useState)({nodes:[],links:[]}),2),y=g[0],p=g[1];Object(u.useEffect)((function(){n.error?d({isError:!0,message:n.error.message}):p(_())}),[n]);var _=function(){var t=n.series[0],e=t.fields.find((function(t){return t.name===i.source})),r=t.fields.find((function(t){return t.name===i.target})),o=t.fields.find((function(t){return t.name===i.value})),s=null==e?void 0:e.values.toArray(),u=null==r?void 0:r.values.toArray(),l=null==o?void 0:o.values.toArray();if(function(t,e,n){var r=!0;if(!(t&&e&&n))return d({isError:!0,message:a}),!1;var o=t.every((function(t){return"string"==typeof t})),i=e.every((function(t){return"string"==typeof t})),s=n.every((function(t){return"number"==typeof t}));return o&&i&&s?(d({}),r):(d({isError:!0,message:"Fields should have the following types: source (string), target (string), value (numeric)"}),!1)}(s,u,l)){var f=c.zip(s,u,l);return{nodes:Array.from(new Set(s.concat(u))).map((function(t){return{name:t}})),links:f.map((function(t){return{source:t[0],target:t[1],value:+t[2].toFixed(2)}}))}}},v=function(t){var n=new et(t).width(r).height(o).align(e.align).edgeColor(e.edgeColor).colorScheme(e.colorScheme).displayValues(e.displayValues).highlightOnHover(e.highlightOnHover).data(y);try{n.render()}catch(t){d({isError:!0,message:t.message})}};return h.isError?l.a.createElement(rt,{message:h.message}):l.a.createElement("svg",{viewBox:"0 0 "+r+" "+o,ref:function(t){c.select(t).selectAll("*").remove(),c.select(t).call(v)}})};function ut(){return function(t){var e=t.series,n=a(t,["series"]),r=e.map((function(t){return Object(o.toDataFrame)(i(i({},t),{fields:t.fields.map((function(t,e,n){var r,a=lt.includes(t.name),s=t.values instanceof o.ArrayVector||"function"==typeof(null===(r=t.values)||void 0===r?void 0:r.toArray),u=Array.isArray(t.values);if(!a||!t.values||!u&&!s)return t;var l=s?t.values.toArray():u?t.values:null;if(null===l)return t;var c=a?l.map((function(t){return"string"==typeof t?t.split("|"):t}))[0].map((function(t,e,n){return Number.isNaN(Number(t))?t:Number(t)})):null;return i(i({},t),{type:(null==c?void 0:c.every((function(t){return"number"==typeof t})))?o.FieldType.number:t.type,values:c?new o.ArrayVector(c):l})}))}))}));return i({series:r},n)}}var lt=["source","target","value"];n.d(e,"plugin",(function(){return ct}));var ct=new o.PanelPlugin((function(t){var e=t.data,n=a(t,["data"]),r=Object(u.useMemo)(ut,[]),o=Object(u.useMemo)((function(){return r(e)}),[r,e]);return l.a.createElement(st,i({},i(i({},n),{data:o})))})).setPanelOptions((function(t){return t.addSelect({path:"align",name:"Align",defaultValue:"Justify",settings:{options:[{value:"Justify",label:"Justify"},{value:"Left",label:"Left"},{value:"Right",label:"Right"},{value:"Center",label:"Center"}]}}).addTextInput({path:"colorArray",name:"Color Object",defaultValue:""}).addSelect({path:"colorScheme",name:"Color",defaultValue:"Tableau10",settings:{options:[{value:"Tableau10",label:"Tableau10"},{value:"Category10",label:"Category10"},{value:"Accent",label:"Accent"},{value:"Dark2",label:"Dark2"},{value:"Paired",label:"Paired"},{value:"Pastel1",label:"Pastel1"},{value:"Pastel2",label:"Pastel2"},{value:"Set1",label:"Set1"},{value:"Set2",label:"Set2"},{value:"Set3",label:"Set3"}]}}).addSelect({path:"edgeColor",name:"Edge Color",defaultValue:"path",settings:{options:[{value:"path",label:"input-output"},{value:"input",label:"input"},{value:"output",label:"output"},{value:"none",label:"none"}]}}).addSelect({path:"displayValues",name:"Display Values",defaultValue:"none",settings:{options:[{value:"total",label:"Totals"},{value:"percentage",label:"Percentages"},{value:"both",label:"Both"},{value:"none",label:"None"}]}}).addBooleanSwitch({path:"highlightOnHover",name:"Highlight connections on node hover",defaultValue:!1})}))}])})); +//# sourceMappingURL=module.js.map \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/module.js.LICENSE.txt b/public/app/plugins/panel/sankey-panel-0.5.0/module.js.LICENSE.txt new file mode 100644 index 0000000000000..c18ab1d93b2fc --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/module.js.LICENSE.txt @@ -0,0 +1,14 @@ +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/module.js.map b/public/app/plugins/panel/sankey-panel-0.5.0/module.js.map new file mode 100644 index 0000000000000..52e71166811b2 --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///external \"react\"","webpack:///external \"d3\"","webpack:///external \"@grafana/data\"","webpack:///external \"@grafana/ui\"","webpack:///../node_modules/tslib/tslib.es6.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/sum.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/max.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/min.js","webpack:///../node_modules/d3-sankey/src/align.js","webpack:///../node_modules/d3-sankey/src/constant.js","webpack:///../node_modules/d3-sankey/src/sankey.js","webpack:///../node_modules/d3-path/src/path.js","webpack:///../node_modules/d3-shape/src/array.js","webpack:///../node_modules/d3-shape/src/constant.js","webpack:///../node_modules/d3-shape/src/point.js","webpack:///../node_modules/d3-shape/src/link/index.js","webpack:///../node_modules/d3-sankey/src/sankeyLinkHorizontal.js","webpack:///./Sankey.js","webpack:///./Error.tsx","webpack:///./SankeyPanel.tsx","webpack:///./transform-fn-data.ts","webpack:///./module.ts","webpack:///./SankeyPanelFn.tsx"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","__WEBPACK_EXTERNAL_MODULE__0__","__WEBPACK_EXTERNAL_MODULE__1__","__WEBPACK_EXTERNAL_MODULE__2__","__WEBPACK_EXTERNAL_MODULE__3__","__assign","assign","arguments","length","apply","this","__rest","e","indexOf","getOwnPropertySymbols","propertyIsEnumerable","__read","iterator","ar","next","done","push","error","sum","values","valueof","undefined","index","max","min","targetDepth","target","depth","left","node","right","height","justify","sourceLinks","center","targetLinks","constant","x","ascendingSourceBreadth","a","b","ascendingBreadth","source","ascendingTargetBreadth","y0","defaultId","defaultNodes","graph","nodes","defaultLinks","links","find","nodeById","id","Error","computeLinkBreadths","y1","link","width","py","sort","linkSort","x0","x1","dx","dy","align","iterations","sankey","computeNodeLinks","computeNodeValues","computeNodeDepths","computeNodeHeights","computeNodeBreadths","entries","Map","map","fixedValue","Math","current","Set","size","add","columns","kx","Array","floor","layer","column","computeNodeLayers","ky","y","reorderLinks","initializeNodeBreadths","alpha","pow","beta","relaxRightToLeft","relaxLeftToRight","w","v","targetTop","reorderNodeLinks","resolveCollisions","sourceTop","subject","resolveCollisionsBottomToTop","resolveCollisionsTopToBottom","update","nodeId","_","nodeAlign","nodeSort","nodeWidth","nodePadding","extent","pi","PI","tau","tauEpsilon","Path","_x0","_y0","_x1","_y1","path","constructor","moveTo","closePath","lineTo","quadraticCurveTo","bezierCurveTo","x2","y2","arcTo","x21","y21","x01","y01","l01_2","abs","x20","y20","l21_2","l20_2","l21","sqrt","l01","tan","acos","t01","t21","arc","a0","a1","ccw","cos","sin","cw","da","rect","h","toString","slice","linkSource","linkTarget","curve","context","buffer","argv","curveHorizontal","horizontalSource","horizontalTarget","DISPLAY_VALUES","EDGE_COLORS","Sankey","svg","container","_svg","_container","_gBound","_data","_nodes","_links","_width","_height","_boundedWidth","_boundedHeight","_marginTop","_marginRight","_marginBottom","_marginLeft","_background","_edgeColor","_colorScheme","_colorScale","_colorArray","_sankeyAlignType","_sankeyAlign","_sankeyGenerator","_sankeyNodeWith","_sankeyNodePadding","_svgNode","_svgLink","_displayValues","_highlightOnHover","_setBoundDimensions","_setColorScale","_configureSankey","_calculateSankey","d3","d3Sankey","sankeyData","gradient","append","attr","uid","random","_color","currentNode","linkedNodes","linkType","nodeType","forEach","step","selectAll","style","linkedNode","percent","nodesAtDepth","filter","totalAtDepth","nodeValue","_formatThousand","nodePercent","_formatPercent","label","data","join","colorArray","JSON","parse","keys","includes","on","_showLinks","_showAll","_setLinkGradient","text","_labelNode","_formatValue","_validate","_init","_renderSVG","message","panelStyles","containerStyles","messageStyles","display","justifyContent","alignItems","padding","marginBottom","position","color","textShadow","borderRadius","flexDirection","background","marginLeft","options","CHART_REQUIRED_FIELDS","requiredFieldsMsg","isError","setError","setGraph","buildGraph","frame","series","sourceAccesor","fields","field","targetAccesor","valueAccesor","sources","toArray","targets","isValid","sourcesString","every","targetsString","valuesNumeric","validate","zip","from","concat","toFixed","chart","edgeColor","colorScheme","displayValues","highlightOnHover","render","renderError","viewBox","ref","remove","transformFnData","other","transformedSeries","__","isSankeyField","SANKEY_FIELD_NAMES","isArrayVector","isArray","parsedValues","split","Number","isNaN","type","number","props","transformFn","transformedData","setPanelOptions","builder","addSelect","defaultValue","settings","addTextInput","addBooleanSwitch"],"mappings":"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","file":"module.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__0__;","module.exports = __WEBPACK_EXTERNAL_MODULE__1__;","module.exports = __WEBPACK_EXTERNAL_MODULE__2__;","module.exports = __WEBPACK_EXTERNAL_MODULE__3__;","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","export default function sum(values, valueof) {\n let sum = 0;\n if (valueof === undefined) {\n for (let value of values) {\n if (value = +value) {\n sum += value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if (value = +valueof(value, ++index, values)) {\n sum += value;\n }\n }\n }\n return sum;\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","import {min} from \"d3-array\";\n\nfunction targetDepth(d) {\n return d.target.depth;\n}\n\nexport function left(node) {\n return node.depth;\n}\n\nexport function right(node, n) {\n return n - 1 - node.height;\n}\n\nexport function justify(node, n) {\n return node.sourceLinks.length ? node.depth : n - 1;\n}\n\nexport function center(node) {\n return node.targetLinks.length ? node.depth\n : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1\n : 0;\n}\n","export default function constant(x) {\n return function() {\n return x;\n };\n}\n","import {max, min, sum} from \"d3-array\";\nimport {justify} from \"./align.js\";\nimport constant from \"./constant.js\";\n\nfunction ascendingSourceBreadth(a, b) {\n return ascendingBreadth(a.source, b.source) || a.index - b.index;\n}\n\nfunction ascendingTargetBreadth(a, b) {\n return ascendingBreadth(a.target, b.target) || a.index - b.index;\n}\n\nfunction ascendingBreadth(a, b) {\n return a.y0 - b.y0;\n}\n\nfunction value(d) {\n return d.value;\n}\n\nfunction defaultId(d) {\n return d.index;\n}\n\nfunction defaultNodes(graph) {\n return graph.nodes;\n}\n\nfunction defaultLinks(graph) {\n return graph.links;\n}\n\nfunction find(nodeById, id) {\n const node = nodeById.get(id);\n if (!node) throw new Error(\"missing: \" + id);\n return node;\n}\n\nfunction computeLinkBreadths({nodes}) {\n for (const node of nodes) {\n let y0 = node.y0;\n let y1 = y0;\n for (const link of node.sourceLinks) {\n link.y0 = y0 + link.width / 2;\n y0 += link.width;\n }\n for (const link of node.targetLinks) {\n link.y1 = y1 + link.width / 2;\n y1 += link.width;\n }\n }\n}\n\nexport default function Sankey() {\n let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent\n let dx = 24; // nodeWidth\n let dy = 8, py; // nodePadding\n let id = defaultId;\n let align = justify;\n let sort;\n let linkSort;\n let nodes = defaultNodes;\n let links = defaultLinks;\n let iterations = 6;\n\n function sankey() {\n const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)};\n computeNodeLinks(graph);\n computeNodeValues(graph);\n computeNodeDepths(graph);\n computeNodeHeights(graph);\n computeNodeBreadths(graph);\n computeLinkBreadths(graph);\n return graph;\n }\n\n sankey.update = function(graph) {\n computeLinkBreadths(graph);\n return graph;\n };\n\n sankey.nodeId = function(_) {\n return arguments.length ? (id = typeof _ === \"function\" ? _ : constant(_), sankey) : id;\n };\n\n sankey.nodeAlign = function(_) {\n return arguments.length ? (align = typeof _ === \"function\" ? _ : constant(_), sankey) : align;\n };\n\n sankey.nodeSort = function(_) {\n return arguments.length ? (sort = _, sankey) : sort;\n };\n\n sankey.nodeWidth = function(_) {\n return arguments.length ? (dx = +_, sankey) : dx;\n };\n\n sankey.nodePadding = function(_) {\n return arguments.length ? (dy = py = +_, sankey) : dy;\n };\n\n sankey.nodes = function(_) {\n return arguments.length ? (nodes = typeof _ === \"function\" ? _ : constant(_), sankey) : nodes;\n };\n\n sankey.links = function(_) {\n return arguments.length ? (links = typeof _ === \"function\" ? _ : constant(_), sankey) : links;\n };\n\n sankey.linkSort = function(_) {\n return arguments.length ? (linkSort = _, sankey) : linkSort;\n };\n\n sankey.size = function(_) {\n return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0];\n };\n\n sankey.extent = function(_) {\n return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]];\n };\n\n sankey.iterations = function(_) {\n return arguments.length ? (iterations = +_, sankey) : iterations;\n };\n\n function computeNodeLinks({nodes, links}) {\n for (const [i, node] of nodes.entries()) {\n node.index = i;\n node.sourceLinks = [];\n node.targetLinks = [];\n }\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d]));\n for (const [i, link] of links.entries()) {\n link.index = i;\n let {source, target} = link;\n if (typeof source !== \"object\") source = link.source = find(nodeById, source);\n if (typeof target !== \"object\") target = link.target = find(nodeById, target);\n source.sourceLinks.push(link);\n target.targetLinks.push(link);\n }\n if (linkSort != null) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(linkSort);\n targetLinks.sort(linkSort);\n }\n }\n }\n\n function computeNodeValues({nodes}) {\n for (const node of nodes) {\n node.value = node.fixedValue === undefined\n ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value))\n : node.fixedValue;\n }\n }\n\n function computeNodeDepths({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.depth = x;\n for (const {target} of node.sourceLinks) {\n next.add(target);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeHeights({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.height = x;\n for (const {source} of node.targetLinks) {\n next.add(source);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeLayers({nodes}) {\n const x = max(nodes, d => d.depth) + 1;\n const kx = (x1 - x0 - dx) / (x - 1);\n const columns = new Array(x);\n for (const node of nodes) {\n const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x))));\n node.layer = i;\n node.x0 = x0 + i * kx;\n node.x1 = node.x0 + dx;\n if (columns[i]) columns[i].push(node);\n else columns[i] = [node];\n }\n if (sort) for (const column of columns) {\n column.sort(sort);\n }\n return columns;\n }\n\n function initializeNodeBreadths(columns) {\n const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value));\n for (const nodes of columns) {\n let y = y0;\n for (const node of nodes) {\n node.y0 = y;\n node.y1 = y + node.value * ky;\n y = node.y1 + py;\n for (const link of node.sourceLinks) {\n link.width = link.value * ky;\n }\n }\n y = (y1 - y + py) / (nodes.length + 1);\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n node.y0 += y * (i + 1);\n node.y1 += y * (i + 1);\n }\n reorderLinks(nodes);\n }\n }\n\n function computeNodeBreadths(graph) {\n const columns = computeNodeLayers(graph);\n py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1));\n initializeNodeBreadths(columns);\n for (let i = 0; i < iterations; ++i) {\n const alpha = Math.pow(0.99, i);\n const beta = Math.max(1 - alpha, (i + 1) / iterations);\n relaxRightToLeft(columns, alpha, beta);\n relaxLeftToRight(columns, alpha, beta);\n }\n }\n\n // Reposition each node based on its incoming (target) links.\n function relaxLeftToRight(columns, alpha, beta) {\n for (let i = 1, n = columns.length; i < n; ++i) {\n const column = columns[i];\n for (const target of column) {\n let y = 0;\n let w = 0;\n for (const {source, value} of target.targetLinks) {\n let v = value * (target.layer - source.layer);\n y += targetTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - target.y0) * alpha;\n target.y0 += dy;\n target.y1 += dy;\n reorderNodeLinks(target);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n // Reposition each node based on its outgoing (source) links.\n function relaxRightToLeft(columns, alpha, beta) {\n for (let n = columns.length, i = n - 2; i >= 0; --i) {\n const column = columns[i];\n for (const source of column) {\n let y = 0;\n let w = 0;\n for (const {target, value} of source.sourceLinks) {\n let v = value * (target.layer - source.layer);\n y += sourceTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - source.y0) * alpha;\n source.y0 += dy;\n source.y1 += dy;\n reorderNodeLinks(source);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n function resolveCollisions(nodes, alpha) {\n const i = nodes.length >> 1;\n const subject = nodes[i];\n resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);\n resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);\n resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha);\n resolveCollisionsTopToBottom(nodes, y0, 0, alpha);\n }\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(nodes, y, i, alpha) {\n for (; i < nodes.length; ++i) {\n const node = nodes[i];\n const dy = (y - node.y0) * alpha;\n if (dy > 1e-6) node.y0 += dy, node.y1 += dy;\n y = node.y1 + py;\n }\n }\n\n // Push any overlapping nodes up.\n function resolveCollisionsBottomToTop(nodes, y, i, alpha) {\n for (; i >= 0; --i) {\n const node = nodes[i];\n const dy = (node.y1 - y) * alpha;\n if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy;\n y = node.y0 - py;\n }\n }\n\n function reorderNodeLinks({sourceLinks, targetLinks}) {\n if (linkSort === undefined) {\n for (const {source: {sourceLinks}} of targetLinks) {\n sourceLinks.sort(ascendingTargetBreadth);\n }\n for (const {target: {targetLinks}} of sourceLinks) {\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n function reorderLinks(nodes) {\n if (linkSort === undefined) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(ascendingTargetBreadth);\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n // Returns the target.y0 that would produce an ideal link from source to target.\n function targetTop(source, target) {\n let y = source.y0 - (source.sourceLinks.length - 1) * py / 2;\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y += width + py;\n }\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y -= width;\n }\n return y;\n }\n\n // Returns the source.y0 that would produce an ideal link from source to target.\n function sourceTop(source, target) {\n let y = target.y0 - (target.targetLinks.length - 1) * py / 2;\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y += width + py;\n }\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y -= width;\n }\n return y;\n }\n\n return sankey;\n}\n","var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n","export var slice = Array.prototype.slice;\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import {path} from \"d3-path\";\nimport {slice} from \"../array.js\";\nimport constant from \"../constant.js\";\nimport {x as pointX, y as pointY} from \"../point.js\";\nimport pointRadial from \"../pointRadial.js\";\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link(curve) {\n var source = linkSource,\n target = linkTarget,\n x = pointX,\n y = pointY,\n context = null;\n\n function link() {\n var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), link) : x;\n };\n\n link.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), link) : y;\n };\n\n link.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nexport function linkHorizontal() {\n return link(curveHorizontal);\n}\n\nexport function linkVertical() {\n return link(curveVertical);\n}\n\nexport function linkRadial() {\n var l = link(curveRadial);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n","import {linkHorizontal} from \"d3-shape\";\n\nfunction horizontalSource(d) {\n return [d.source.x1, d.y0];\n}\n\nfunction horizontalTarget(d) {\n return [d.target.x0, d.y1];\n}\n\nexport default function() {\n return linkHorizontal()\n .source(horizontalSource)\n .target(horizontalTarget);\n}\n","import * as d3 from 'd3';\nimport * as d3Sankey from 'd3-sankey';\n\nconst DISPLAY_VALUES = { total: 'total', percentage: 'percentage', both: 'both', none: 'none' };\nconst EDGE_COLORS = { none: 'none', path: 'path', input: 'input', output: 'output'};\n\nexport class Sankey {\n constructor(svg, container) {\n this._svg = svg;\n this._container = container || svg;\n this._gBound = null;\n\n this._data = null;\n this._nodes = null;\n this._links = null;\n\n this._width = 0;\n this._height = 0;\n this._boundedWidth = 0;\n this._boundedHeight = 0;\n\n this._marginTop = 20;\n this._marginRight = 20;\n this._marginBottom = 20;\n this._marginLeft = 20;\n\n this._background = 'rgba(0, 0, 0, 0)';\n this._edgeColor = 'path';\n this._colorScheme = 'Tableau10';\n this._colorScale = null;\n this._colorArray = '';\n\n this._sankeyAlignType = 'Justify';\n this._sankeyAlign = null;\n this._sankeyGenerator = null;\n this._sankeyNodeWith = 85;\n this._sankeyNodePadding = 20;\n\n this._svgNode = null;\n this._svgLink = null;\n\n this._displayValues = 'none';\n this._highlightOnHover = false;\n\n }\n \n _init() {\n this._setBoundDimensions();\n this._setColorScale();\n this._configureSankey();\n this._calculateSankey();\n }\n\n // ---------------------------- DIMENSIONS ----------------------------\n\n _setBoundDimensions() {\n this._boundedWidth = this._width - this._marginLeft - this._marginRight;\n this._boundedHeight = this._height - this._marginTop - this._marginBottom;\n }\n\n // ------------------------------ COLOR -------------------------------\n\n _setColorScale() {\n this._colorScale = d3.scaleOrdinal(d3[`scheme${this._colorScheme}`]);\n }\n\n _color(node) {\n return this._colorScale(node.name);\n }\n\n // ------------------------------ SANKEY -------------------------------\n\n _configureSankey() {\n this._sankeyAlign = d3Sankey[`sankey${this._sankeyAlignType}`];\n\n this._sankeyGenerator = d3Sankey\n .sankey()\n .nodeId(d => d.name)\n .nodeAlign(this._sankeyAlign)\n .nodeWidth(this._sankeyNodeWith)\n .nodePadding(this._sankeyNodePadding)\n .extent([\n [0, 0],\n [this._boundedWidth, this._boundedHeight],\n ]);\n }\n\n _calculateSankey() {\n const sankeyData = this._sankeyGenerator({\n nodes: this._data.nodes.map(d => Object.assign({}, d)),\n links: this._data.links.map(d => Object.assign({}, d))\n });\n\n this._nodes = sankeyData.nodes;\n this._links = sankeyData.links;\n }\n\n // ---------------------------- VALIDATIONS -----------------------------\n\n _validate() {\n return this._data &&\n this._data.nodes &&\n this._data.links &&\n this._data.nodes.length > 0 &&\n this._data.links.length > 0\n }\n\n // ------------------------------ HELPERS -------------------------------\n\n _setLinkGradient() {\n const gradient = this._svgLink\n .append('linearGradient')\n .attr('id', d => (d.uid = `link-${d.index}-${Math.random()}`))\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', d => d.source.x1)\n .attr('x2', d => d.target.x0);\n\n gradient\n .append('stop')\n .attr('offset', '0%')\n .attr('stop-color', d => this._color(d.source));\n\n gradient\n .append('stop')\n .attr('offset', '100%')\n .attr('stop-color', d => this._color(d.target));\n }\n\n _setLinkStroke(d) {\n switch (this._edgeColor) {\n case EDGE_COLORS.none:\n return '#aaa';\n case EDGE_COLORS.path:\n return `url(#${d.uid})`;\n case EDGE_COLORS.input:\n return this._color(d.source)\n case EDGE_COLORS.output:\n return this._color(d.target)\n default:\n return\n }\n }\n\n // NODE HOVER\n _showLinks(currentNode) {\n const linkedNodes = [];\n\n let traverse = [\n {\n linkType: 'sourceLinks',\n nodeType: 'target',\n },\n {\n linkType: 'targetLinks',\n nodeType: 'source',\n },\n ];\n\n traverse.forEach(step => {\n currentNode[step.linkType].forEach(l => {\n linkedNodes.push(l[step.nodeType]);\n });\n });\n\n // highlight linked nodes\n this._gBound\n .selectAll('.sankey-node')\n .style('opacity', node =>\n currentNode.name === node.name ||\n linkedNodes.find(linkedNode => linkedNode.name === node.name) ? \n '1' : '0.2'\n );\n\n // highlight links\n this._gBound\n .selectAll('.sankey-link')\n .style('opacity', link =>\n link && (\n link.source.name === currentNode.name || \n link.target.name === currentNode.name\n ) ? \n '1' : '0.2'\n );\n };\n\n _showAll() {\n this._gBound.selectAll('.sankey-node').style('opacity', '1');\n this._gBound.selectAll('.sankey-link').style('opacity', '1');\n };\n\n // NODE LABELING\n _formatValue(value) { return d3.format('.2~f')(value); }\n _formatPercent(percent) { return d3.format('.2~%')(percent); }\n _formatThousand(value) { return d3.format('.3~s')(value); }\n\n _labelNode(currentNode) {\n const nodesAtDepth = this._nodes.filter(node => node.depth === currentNode.depth);\n const totalAtDepth = d3.sum(nodesAtDepth, node => node.value);\n const nodeValue = this._formatThousand(currentNode.value);\n const nodePercent = this._formatPercent(currentNode.value / totalAtDepth);\n\n let label = currentNode.name;\n switch (this._displayValues) {\n case DISPLAY_VALUES.total:\n label = `${label}\n ${nodeValue}`;\n break;\n case DISPLAY_VALUES.percentage:\n label = `${label}\n ${nodePercent}`;\n break;\n case DISPLAY_VALUES.both:\n label = `${label}\n ${nodePercent} - ${nodeValue}`;\n break;\n default:\n break;\n }\n return label;\n };\n\n // ------------------------------ DRAWING -------------------------------\n\n _renderSVG() {\n // BACKGROUND\n this._container.style('background-color', this._background)\n\n // BOUNDS\n this._gBound = this._container.append('g')\n .attr('transform', `translate(${this._marginLeft}, ${this._marginTop})`);\n\n // NODES\n this._svgNode = this._gBound\n .append('g')\n .attr('stroke', '#000')\n .selectAll('.sankey-node')\n .data(this._nodes, node => node.name)\n .join('rect')\n .attr('class', 'sankey-node')\n .attr('id', d => d.name)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('height', d => d.y1 - d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('stroke', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .attr('fill', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .on('mouseover', d => this._highlightOnHover && this._showLinks(d))\n .on('mouseout', _ => this._highlightOnHover && this._showAll());\n\n // LINKS\n this._svgLink = this._gBound\n .append('g')\n .attr('fill', 'none')\n .attr('stroke-opacity', 0.3)\n .selectAll('g')\n .data(this._links, link => `${link.source.name}-${link.target.name}`)\n .join('g')\n .style('mix-blend-mode', 'multiply');\n\n if (this._edgeColor === 'path') this._setLinkGradient()\n\n this._svgLink\n .append('path')\n .attr('class', 'sankey-link')\n .attr('d', d3Sankey.sankeyLinkHorizontal())\n .attr('stroke', \"rgba(182, 185, 196, 1)\")\n .attr('stroke-width', d => Math.max(1, d.width)); \n\n // LABELS\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('y', d => (d.y1 + d.y0) / 2)\n .attr('dy', '0.35em')\n //.attr('text-anchor', d => (d.x0 < this._width / 2 ? 'start' : 'end'))\n .text(d => this._labelNode(d));\n\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('font-size', 14)\n .attr('font-weight', '700')\n .attr('y', d => ((d.y1 + d.y0) / 2) + 16)\n .attr('dy', '0.35em')\n //.attr('text-anchor', d => (d.x0 < this._width / 2 ? 'start' : 'end'))\n .text(d => this._formatValue(d.value));\n\n this._svgNode\n .append('title')\n .text(d => `${d.name}\\n${this._formatValue(d.value)}`);\n\n this._svgLink\n .append('title')\n .text(d => `${d.source.name} → ${d.target.name}\\n${this._formatValue(d.value)}`);\n }\n\n\n // ----------------------------------------------------------------------- \n // ------------------------------ API ------------------------------\n // ----------------------------------------------------------------------- \n\n data(_) {\n return arguments.length ? (this._data = _, this) : this._data;\n };\n\n width(_) {\n return arguments.length ? (this._width = +_, this) : this._width;\n };\n\n height(_) {\n return arguments.length ? (this._height = +_, this) : this._height;\n };\n\n align(_) {\n return arguments.length ? (this._sankeyAlignType = _, this) : this._sankeyAlignType;\n }\n\n colorScheme(_) {\n return arguments.length ? (this._colorScheme = _, this) : this._colorScheme;\n }\n\n colorArray(_) {\n return arguments.length ? (this._colorArray = _, this) : this._colorArray;\n }\n\n edgeColor(_) {\n return arguments.length ? (this._edgeColor = _, this) : this._edgeColor;\n }\n\n displayValues(_) {\n return arguments.length ? (this._displayValues = _, this) : this._displayValues;\n }\n\n highlightOnHover(_) {\n return arguments.length ? (this._highlightOnHover = _, this) : this._highlightOnHover;\n }\n\n render() {\n if (!this._validate()) {\n // no graph data\n }\n else {\n this._init();\n this._renderSVG()\n }\n return this;\n }\n}\n","// @ts-nocheck\nimport React from 'react';\nimport { Icon } from '@grafana/ui';\n\nexport const ErrorMessage = ({ message }) => ( \n

\n

\n \n
{message}
\n
\n

\n)\n\nconst panelStyles = {\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n}\n\nconst containerStyles = {\n padding: '15px 20px',\n marginBottom: '4px',\n position: 'relative',\n color: 'rgb(255, 255, 255)',\n textShadow: 'rgb(0 0 0 / 20%) 0px 1px 0px',\n borderRadius: '3px',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n background: 'linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))'\n}\n\nconst messageStyles = {\n marginLeft: 10\n}\n","// @ts-nocheck\nimport React, { useState, useEffect } from 'react';\nimport * as d3 from 'd3';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyOptions } from 'types';\nimport { Sankey } from 'Sankey'\nimport { ErrorMessage } from 'Error'\n\ninterface Props extends PanelProps {}\n\nexport const SankeyPanel: React.FC = ({ options, data, width, height }) => {\n // ------------------------ CHART CONSTANTS -----------------------\n const CHART_REQUIRED_FIELDS = { source: 'source', target: 'target', value: 'value' };\n\n // ------------------------ ERROR MESSAGES ------------------------\n const requiredFieldsMsg = `Required fields not present: ${Object.keys(CHART_REQUIRED_FIELDS).join(', ')}`;\n const fieldTypeMsg = `Fields should have the following types: source (string), target (string), value (numeric)`;\n\n // ------------------------- REACT HOOKS --------------------------\n const [ error, setError ] = useState({ isError: false, message: '' })\n const [ graph, setGraph ] = useState({ nodes: [], links: [] })\n\n useEffect(() => {\n data.error\n ?\n setError({isError: true, message: data.error.message})\n :\n setGraph(buildGraph())\n }, [data])\n\n // ------------------------- DATA ACQUISITION -------------------------\n const validate = (sources, targets, values) => {\n let isValid = true;\n\n // REQUIRED FIELDS\n if (!(sources && targets && values)) {\n setError({ isError: true, message: requiredFieldsMsg })\n return isValid = false;\n }\n\n // FIELD TYPES\n const sourcesString = sources.every(d => typeof d === 'string')\n const targetsString = targets.every(d => typeof d === 'string')\n const valuesNumeric = values.every(d => typeof d === 'number')\n\n if (!(sourcesString && targetsString && valuesNumeric)) {\n setError({ isError: true, message: fieldTypeMsg })\n return isValid = false;\n }\n\n setError({});\n\n return isValid;\n }\n\n const buildGraph = () => {\n const frame = data.series[0];\n\n const sourceAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.source);\n const targetAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.target);\n const valueAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.value);\n\n const sources = sourceAccesor?.values.toArray();\n const targets = targetAccesor?.values.toArray();\n const values = valueAccesor?.values.toArray();\n\n const isValid = validate(sources, targets, values);\n if (!isValid) {return}\n \n const zip = d3.zip(sources, targets, values);\n \n const nodes = Array.from(new Set(sources.concat(targets))).map(node => ({ name: node }));\n const links = zip.map(d => ({ source: d[0], target: d[1], value: +d[2].toFixed(2) }));\n const graph = { nodes, links };\n\n return graph\n }\n\n // ------------------------------- CHART ------------------------------\n const chart = svg => {\n const sankey = new Sankey(svg)\n .width(width)\n .height(height)\n .align(options.align)\n .edgeColor(options.edgeColor)\n .colorScheme(options.colorScheme)\n .displayValues(options.displayValues)\n .highlightOnHover(options.highlightOnHover)\n .data(graph)\n\n try {\n sankey.render();\n } catch (renderError) {\n setError({isError: true, message: renderError.message})\n }\n };\n\n return (error.isError ?\n \n :\n {\n d3.select(node)\n .selectAll('*')\n .remove();\n d3.select(node).call(chart);\n }}\n />\n );\n};\n","// NOTE: implementation of toDataFrame: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/dataframe/processDataFrame.ts\nimport { toDataFrame, FieldType, ArrayVector, Field } from '@grafana/data';\n\nimport { SankeyOptionsFn } from 'types-fn';\n\nexport function transformFnData(): Required['transformFn'] {\n return ({ series, ...other }) => {\n const transformedSeries = series.map((data) => {\n return toDataFrame({ ...data, fields: data.fields.map(mapField()) });\n });\n\n return {\n series: transformedSeries,\n ...other,\n };\n };\n}\n\nconst SANKEY_FIELD_NAMES = ['source', 'target', 'value'];\n\n// @ts-ignore\nfunction mapField

() {\n return (field: Field

, _: number, __: Array>) => {\n const isSankeyField = SANKEY_FIELD_NAMES.includes(field.name);\n\n const isArrayVector = field.values instanceof ArrayVector || typeof field.values?.toArray === 'function';\n const isArray = Array.isArray(field.values);\n\n if (!isSankeyField || !field.values || (!isArray && !isArrayVector)) {\n return field;\n }\n\n const values = isArrayVector ? field.values.toArray() : isArray ? field.values : null;\n\n if (values === null) {\n return field;\n }\n\n const parsedValues = isSankeyField ? ((values as P[]).map(splitValue())[0] as unknown[]).map(mapToNumber()) : null;\n\n return {\n ...field,\n type: parsedValues?.every(isNumber()) ? FieldType.number : field.type,\n values: parsedValues ? new ArrayVector(parsedValues) : values,\n };\n };\n}\n\n// @ts-ignore\nfunction mapToNumber() {\n return (value: V, _: number, __: V[]) => (Number.isNaN(Number(value)) ? value : Number(value));\n}\n\n// @ts-ignore\nfunction splitValue() {\n return (value: V) => (typeof value === 'string' ? value.split('|') : value);\n}\n\n// @ts-ignore\nfunction isNumber() {\n return (value: V) => typeof value === 'number';\n}\n","import { PanelPlugin } from '@grafana/data';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { SankeyPanelFn as SankeyPanel } from './SankeyPanelFn';\n\nexport const plugin = new PanelPlugin(SankeyPanel).setPanelOptions((builder) => {\n return builder\n .addSelect({\n path: 'align',\n name: 'Align',\n defaultValue: 'Justify',\n settings: {\n options: [\n {\n value: 'Justify',\n label: 'Justify',\n },\n {\n value: 'Left',\n label: 'Left',\n },\n {\n value: 'Right',\n label: 'Right',\n },\n {\n value: 'Center',\n label: 'Center',\n },\n ],\n },\n })\n .addTextInput({\n path: 'colorArray',\n name: 'Color Object',\n defaultValue: '',\n })\n .addSelect({\n path: 'colorScheme',\n name: 'Color',\n defaultValue: 'Tableau10',\n settings: {\n options: [\n {\n value: 'Tableau10',\n label: 'Tableau10',\n },\n {\n value: 'Category10',\n label: 'Category10',\n },\n {\n value: 'Accent',\n label: 'Accent',\n },\n {\n value: 'Dark2',\n label: 'Dark2',\n },\n {\n value: 'Paired',\n label: 'Paired',\n },\n {\n value: 'Pastel1',\n label: 'Pastel1',\n },\n {\n value: 'Pastel2',\n label: 'Pastel2',\n },\n {\n value: 'Set1',\n label: 'Set1',\n },\n {\n value: 'Set2',\n label: 'Set2',\n },\n {\n value: 'Set3',\n label: 'Set3',\n },\n ],\n },\n })\n .addSelect({\n path: 'edgeColor',\n name: 'Edge Color',\n defaultValue: 'path',\n settings: {\n options: [\n {\n value: 'path',\n label: 'input-output',\n },\n {\n value: 'input',\n label: 'input',\n },\n {\n value: 'output',\n label: 'output',\n },\n {\n value: 'none',\n label: 'none',\n },\n ],\n },\n })\n .addSelect({\n path: 'displayValues',\n name: 'Display Values',\n defaultValue: 'none',\n settings: {\n options: [\n {\n value: 'total',\n label: 'Totals',\n },\n {\n value: 'percentage',\n label: 'Percentages',\n },\n {\n value: 'both',\n label: 'Both',\n },\n {\n value: 'none',\n label: 'None',\n },\n ],\n },\n })\n .addBooleanSwitch({\n path: 'highlightOnHover',\n name: 'Highlight connections on node hover',\n defaultValue: false,\n });\n});\n","import React, { useMemo, FC } from 'react';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyPanel } from 'SankeyPanel';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { transformFnData } from 'transform-fn-data';\n\nexport interface SankeyPanelFnProps extends PanelProps {}\n\nexport const SankeyPanelFn: FC = ({ data, ...props }) => {\n const transformFn = useMemo(transformFnData, []);\n\n const transformedData = useMemo(() => transformFn(data), [transformFn, data]);\n\n return ;\n};\n"],"sourceRoot":""} \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json b/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json new file mode 100644 index 0000000000000..ed100c1ee1689 --- /dev/null +++ b/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json @@ -0,0 +1,39 @@ +{ + "type": "panel", + "name": "sankey-panel", + "id": "ismael-sankey-panel", + "info": { + "description": "Sankey chart panel for grafana using d3", + "author": { + "name": "Ismael", + "url": "" + }, + "keywords": [ + "sankey", + "d3", + "grafana", + "panel" + ], + "logos": { + "small": "img/logo.svg", + "large": "img/logo.svg" + }, + "links": [ + { + "name": "Website", + "url": "https://github.com/grafana/simple-react-panel" + }, + { + "name": "License", + "url": "https://github.com/grafana/simple-react-panel/blob/master/LICENSE" + } + ], + "screenshots": [], + "version": "1.0.0", + "updated": "2022-12-23" + }, + "dependencies": { + "grafanaVersion": "7.0.x", + "plugins": [] + } +} \ No newline at end of file diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index 6697ec42208f2..034c9e2dab632 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -1,6 +1,11 @@ -import { configureStore as reduxConfigureStore, createListenerMiddleware } from '@reduxjs/toolkit'; -import { setupListeners } from '@reduxjs/toolkit/query'; -import { Middleware } from 'redux'; +import { + configureStore as reduxConfigureStore, + EnhancedStore, + MiddlewareArray, + PreloadedState, +} from '@reduxjs/toolkit'; +import { AnyAction, CombinedState } from 'redux'; +import { ThunkMiddleware } from 'redux-thunk'; import { browseDashboardsAPI } from 'app/features/browse-dashboards/api/browseDashboardsAPI'; import { publicDashboardApi } from 'app/features/dashboard/api/publicDashboardApi'; @@ -15,6 +20,12 @@ import { queryLibraryApi } from '../features/query-library/api/factory'; import { setStore } from './store'; +export type ConfiguredStore = EnhancedStore< + CombinedState, + AnyAction, + MiddlewareArray<[ThunkMiddleware, AnyAction>]> +>; + export function addRootReducer(reducers: any) { // this is ok now because we add reducers before configureStore is called // in the future if we want to add reducers during runtime @@ -22,14 +33,7 @@ export function addRootReducer(reducers: any) { addReducer(reducers); } -const listenerMiddleware = createListenerMiddleware(); -const extraMiddleware: Middleware[] = []; - -export function addExtraMiddleware(middleware: Middleware) { - extraMiddleware.push(middleware); -} - -export function configureStore(initialState?: Partial) { +export function configureStore>>(initialState?: I | Promise) { const store = reduxConfigureStore({ reducer: createRootReducer(), middleware: (getDefaultMiddleware) => diff --git a/public/app/types/dashboard.ts b/public/app/types/dashboard.ts index 395255e278405..b480d51b759ee 100644 --- a/public/app/types/dashboard.ts +++ b/public/app/types/dashboard.ts @@ -120,6 +120,7 @@ export interface DashboardInitError { export enum KioskMode { TV = 'tv', Full = 'full', + FN = 'fluxNinja', } export type GetMutableDashboardModelFn = () => DashboardModel | null; diff --git a/public/app/types/window.d.ts b/public/app/types/window.d.ts index bf4e7c5f049e5..18a6cd977b65a 100644 --- a/public/app/types/window.d.ts +++ b/public/app/types/window.d.ts @@ -6,11 +6,7 @@ export declare global { __grafana_load_failed: () => void; public_cdn_path: string; nonce: string | undefined; - System: typeof System; - } - - // Augment DOMParser to accept TrustedType sanitised content - interface DOMParser { - parseFromString(string: string | TrustedType, type: DOMParserSupportedType): Document; + __POWERED_BY_QIANKUN__: boolean; + __INJECTED_PUBLIC_PATH_BY_QIANKUN__: string; } } diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html new file mode 100644 index 0000000000000..eafa6f69773ec --- /dev/null +++ b/public/microfrontends/fn_dashboard/index.html @@ -0,0 +1,35 @@ + + + + FluxNinja Microfrontend + + + + + +

+ + + + + + + + + + diff --git a/public/sass/_variables.dark.generated.scss b/public/sass/_variables.dark.generated.scss index 868c07b7a7342..22dbb1b05cc12 100644 --- a/public/sass/_variables.dark.generated.scss +++ b/public/sass/_variables.dark.generated.scss @@ -14,18 +14,18 @@ $theme-name: dark; -$colors-action-hover: rgba(204, 204, 220, 0.16); -$colors-action-selected: rgba(204, 204, 220, 0.12); +$colors-action-hover: rgba(219, 217, 215, 0.16); +$colors-action-selected: rgba(219, 217, 215, 0.12); // New Colors // ------------------------- -$blue-light: #6E9FFF; -$blue-base: #3D71D9; -$blue-shade: rgb(90, 134, 222); +$blue-light: #F0E4B6; +$blue-base: #3F8367; +$blue-shade: rgb(91, 149, 125); $red-base: #D10E5C; $red-shade: rgb(215, 50, 116); -$green-base: #1A7F4B; -$green-shade: rgb(60, 146, 102); +$green-base: #4BBF73; +$green-shade: rgb(102, 200, 136); $orange-dark: #ff780a; $gray98: #f7f8fa; @@ -61,14 +61,14 @@ $gray-6: #f4f5f8; $white: #ffffff; -$layer0: #111217; -$layer1: #181b1f; -$layer2: #22252b; +$layer0: #312D2B; +$layer1: #3B3835; +$layer2: #5E5855; -$divider: rgba(204, 204, 220, 0.12); +$divider: rgba(219, 217, 215, 0.07); -$border0: rgba(204, 204, 220, 0.12); -$border1: rgba(204, 204, 220, 0.20); +$border0: rgba(219, 217, 215, 0.07); +$border1: rgba(219, 217, 215, 0.15); // Accent colors // ------------------------- @@ -77,37 +77,37 @@ $red: $red-base; $yellow: #ecbb13; $orange: #eb7b18; $purple: #9933cc; -$variable: #6E9FFF; +$variable: #F0E4B6; $brand-primary: #eb7b18; -$brand-success: #1A7F4B; -$brand-warning: #FF9900; +$brand-success: #4BBF73; +$brand-warning: #CF8E07; $brand-danger: #D10E5C; $query-red: #FF5286; -$query-green: #6CCF8E; +$query-green: #318B50; $query-purple: #fe85fc; $query-orange: #eb7b18; // Status colors // -------------------------¨ -$online: #6CCF8E; -$warn: #fbad37; +$online: #318B50; +$warn: #DBD9D7; $critical: #FF5286; // Scaffolding // ------------------------- -$body-bg: #111217; -$page-bg: #111217; -$dashboard-bg: #111217; - -$text-color-strong: #FFFFFF; -$text-color: rgb(204, 204, 220); -$text-color-semi-weak: rgba(204, 204, 220, 0.65); -$text-color-weak: rgba(204, 204, 220, 0.65); -$text-color-faint: rgba(204, 204, 220, 0.6); -$text-color-emphasis: #FFFFFF; -$text-blue: #6E9FFF; +$body-bg: #312D2B; +$page-bg: #312D2B; +$dashboard-bg: #312D2B; + +$text-color-strong: #F0E4B6; +$text-color: #DBD9D7; +$text-color-semi-weak: #F0E4B6; +$text-color-weak: #F0E4B6; +$text-color-faint: #9DA7B8; +$text-color-emphasis: #F0E4B6; +$text-blue: #F0E4B6; $text-shadow-faint: 1px 1px 4px rgb(45, 45, 45); $textShadow: none; @@ -118,14 +118,14 @@ $brand-gradient-vertical: linear-gradient(0.01deg, #F55F3E 0.01%, #FF8833 99.99% // Links // ------------------------- -$link-color: rgb(204, 204, 220); -$link-color-disabled: rgba(204, 204, 220, 0.6); -$link-hover-color: #FFFFFF; -$external-link-color: #6E9FFF; +$link-color: #DBD9D7; +$link-color-disabled: #9DA7B8; +$link-hover-color: #F0E4B6; +$external-link-color: #F0E4B6; // Typography // ------------------------- -$headings-color: rgb(204, 204, 220); +$headings-color: #DBD9D7; $abbr-border-color: $gray-2 !default; $text-muted: $text-color-weak; @@ -133,30 +133,30 @@ $hr-border-color: $dark-9; // Panel // ------------------------- -$panel-bg: #181b1f; -$panel-border: 1px solid rgba(204, 204, 220, 0.12); -$panel-header-hover-bg: rgba(204, 204, 220, 0.16); +$panel-bg: #3B3835; +$panel-border: 1px solid rgba(219, 217, 215, 0.07); +$panel-header-hover-bg: rgba(219, 217, 215, 0.16); $panel-box-shadow: none; $panel-corner: $panel-bg; // page header -$page-header-bg: #111217; +$page-header-bg: #312D2B; $page-header-shadow: inset 0px -4px 14px $dark-3; -$page-header-border-color: #111217; +$page-header-border-color: #312D2B; $divider-border-color: $gray-1; // Graphite Target Editor -$tight-form-func-bg: #22252b; -$tight-form-func-highlight-bg: rgb(40, 43, 49); +$tight-form-func-bg: #5E5855; +$tight-form-func-highlight-bg: rgb(98, 93, 90); -$modal-backdrop-bg: rgba(204, 204, 220, 0.16); +$modal-backdrop-bg: rgba(219, 217, 215, 0.16); $code-tag-bg: $dark-1; $code-tag-border: $dark-9; // cards -$card-background: #22252b; -$card-background-hover: rgb(40, 43, 49); +$card-background: #5E5855; +$card-background-hover: rgb(98, 93, 90); $card-shadow: none; // Lists @@ -164,7 +164,7 @@ $list-item-bg: $card-background; $list-item-hover-bg: $card-background-hover; $list-item-shadow: $card-shadow; -$empty-list-cta-bg: #22252b; +$empty-list-cta-bg: #5E5855; // Scrollbars $scrollbarBackground: #404357; @@ -173,10 +173,10 @@ $scrollbarBorder: black; // Tables // ------------------------- -$table-bg-accent: #22252b; -$table-border: rgba(204, 204, 220, 0.20); -$table-bg-odd: rgb(28, 31, 35); -$table-bg-hover: rgb(35, 38, 42); +$table-bg-accent: #5E5855; +$table-border: rgba(219, 217, 215, 0.15); +$table-bg-odd: rgb(62, 59, 57); +$table-bg-hover: rgb(68, 65, 63); // Buttons // ------------------------- @@ -212,16 +212,16 @@ $btn-active-box-shadow: 0px 0px 4px rgba(255, 120, 10, 0.5); // Forms // ------------------------- -$input-bg: #111217; -$input-bg-disabled: rgba(204, 204, 220, 0.04); +$input-bg: #312D2B; +$input-bg-disabled: rgba(219, 217, 215, 0.04); -$input-color: rgb(204, 204, 220); -$input-border-color: rgba(204, 204, 220, 0.20); +$input-color: #DBD9D7; +$input-border-color: rgba(219, 217, 215, 0.15); $input-box-shadow: none; -$input-border-focus: #6E9FFF; -$input-box-shadow-focus: #6E9FFF !default; -$input-color-placeholder: rgba(204, 204, 220, 0.6); -$input-label-bg: #22252b; +$input-border-focus: #ffffff00; +$input-box-shadow-focus: #ffffff00 !default; +$input-color-placeholder: #9DA7B8; +$input-label-bg: #5E5855; $input-color-select-arrow: $white; // Search @@ -234,11 +234,11 @@ $typeahead-selected-color: $yellow; // Dropdowns // ------------------------- -$dropdownBackground: #181b1f; -$dropdownBorder: rgba(204, 204, 220, 0.12); -$dropdownDividerTop: rgba(204, 204, 220, 0.12); -$dropdownDividerBottom: rgba(204, 204, 220, 0.12); -$dropdownShadow: 0px 8px 24px rgb(1, 4, 9); +$dropdownBackground: #3B3835; +$dropdownBorder: rgba(219, 217, 215, 0.07); +$dropdownDividerTop: rgba(219, 217, 215, 0.07); +$dropdownDividerBottom: rgba(219, 217, 215, 0.07); +$dropdownShadow: 0px 8px 24px rgb(1,4,9); $dropdownLinkColor: $link-color; $dropdownLinkColorHover: $white; @@ -259,16 +259,16 @@ $navbarBorder: 1px solid $dark-6; $side-menu-bg: $panel-bg; $side-menu-bg-mobile: $panel-bg; $side-menu-border: none; -$side-menu-item-hover-bg: #22252b; +$side-menu-item-hover-bg: #5E5855; $side-menu-shadow: 0 0 30px #111; $side-menu-icon-color: #9fa7b3; -$side-menu-header-color: rgb(204, 204, 220); +$side-menu-header-color: #DBD9D7; // Menu dropdowns // ------------------------- -$menu-dropdown-bg: #181b1f; -$menu-dropdown-hover-bg: rgba(204, 204, 220, 0.16); -$menu-dropdown-shadow: 0px 8px 24px rgb(1, 4, 9); +$menu-dropdown-bg: #3B3835; +$menu-dropdown-hover-bg: rgba(219, 217, 215, 0.16); +$menu-dropdown-shadow: 0px 8px 24px rgb(1,4,9); // Tabs // ------------------------- @@ -276,14 +276,14 @@ $tab-border-color: $dark-9; // Form states and alerts // ------------------------- -$warning-text-color: #fbad37; +$warning-text-color: #DBD9D7; $error-text-color: #FF5286; -$success-text-color: #6CCF8E; +$success-text-color: #318B50; $alert-error-bg: #D10E5C; -$alert-success-bg: #1A7F4B; -$alert-warning-bg: #FF9900; -$alert-info-bg: #FF9900; +$alert-success-bg: #4BBF73; +$alert-warning-bg: #CF8E07; +$alert-info-bg: #CF8E07; // Tooltips and popovers // ------------------------- @@ -292,17 +292,17 @@ $tooltipLinkColor: $link-color; $tooltipExternalLinkColor: $external-link-color; $graph-tooltip-bg: $dark-1; -$tooltipBackground: #22252b; -$tooltipColor: rgb(204, 204, 220); -$tooltipArrowColor: #22252b; +$tooltipBackground: #5E5855; +$tooltipColor: #DBD9D7; +$tooltipArrowColor: #5E5855; $tooltipBackgroundError: #D10E5C; $tooltipShadow: 0px 4px 8px rgba(1, 4, 9, 0.75); -$popover-bg: #181b1f; -$popover-color: rgb(204, 204, 220); -$popover-border-color: rgba(204, 204, 220, 0.12); -$popover-header-bg: #22252b; -$popover-shadow: 0px 8px 24px rgb(1, 4, 9); +$popover-bg: #3B3835; +$popover-color: #DBD9D7; +$popover-border-color: rgba(219, 217, 215, 0.07); +$popover-header-bg: #5E5855; +$popover-shadow: 0px 8px 24px rgb(1,4,9); $popover-help-bg: $tooltipBackground; $popover-help-color: $text-color; @@ -337,14 +337,14 @@ $json-explorer-url-color: #027bff; // Changelog and diff // ------------------------- -$diff-label-bg: rgba(204, 204, 220, 0.16); +$diff-label-bg: rgba(219, 217, 215, 0.16); $diff-label-fg: $white; -$diff-group-bg: #22252b; +$diff-group-bg: #5E5855; $diff-arrow-color: $white; -$diff-json-bg: #22252b; -$diff-json-fg: rgb(204, 204, 220); +$diff-json-bg: #5E5855; +$diff-json-fg: #DBD9D7; $diff-json-added: $blue-shade; $diff-json-deleted: $red-shade; diff --git a/public/sass/_variables.generated.scss b/public/sass/_variables.generated.scss index 1a2e11a065177..2bef322ac1d4b 100644 --- a/public/sass/_variables.generated.scss +++ b/public/sass/_variables.generated.scss @@ -99,9 +99,9 @@ $height-lg: 48; // Typography // ------------------------- /* stylelint-disable-next-line string-quotes */ -$font-family-sans-serif: "Inter", "Helvetica", "Arial", sans-serif; +$font-family-sans-serif: Nunito, Roboto, Arial; /* stylelint-disable-next-line string-quotes */ -$font-family-monospace: 'Roboto Mono', monospace; +$font-family-monospace: 'Nunito Mono', monospace; $font-file-path: '../fonts' !default; diff --git a/public/sass/_variables.light.generated.scss b/public/sass/_variables.light.generated.scss index 7d4fac1eb1504..552a95785eb54 100644 --- a/public/sass/_variables.light.generated.scss +++ b/public/sass/_variables.light.generated.scss @@ -14,18 +14,18 @@ $theme-name: light; -$colors-action-hover: rgba(36, 41, 46, 0.12); -$colors-action-selected: rgba(36, 41, 46, 0.08); +$colors-action-hover: rgba(45, 51, 62, 0.12); +$colors-action-selected: #F27A40; // New Colors // ------------------------- -$blue-light: #1F62E0; -$blue-base: #3871DC; -$blue-shade: rgb(44, 90, 176); +$blue-light: #F0E4B6; +$blue-base: #8EC4AD; +$blue-shade: rgb(113, 156, 138); $red-base: #E0226E; $red-shade: rgb(179, 27, 88); -$green-base: #1B855E; -$green-shade: rgb(21, 106, 75); +$green-base: #83D39E; +$green-shade: rgb(104, 168, 126); $orange-dark: #ff780a; $gray98: #f7f8fa; @@ -57,26 +57,26 @@ $gray-7: #fbfbfb; $white: #ffffff; -$layer0: #F4F5F5; -$layer1: #FFFFFF; -$layer2: #F4F5F5; +$layer0: #F6F5F3; +$layer1: #FDFDFC; +$layer2: #FDFDFC; -$divider: rgba(36, 41, 46, 0.12); -$border0: rgba(36, 41, 46, 0.12); -$border1: rgba(36, 41, 46, 0.30); +$divider: rgba(45, 51, 62, 0.12); +$border0: rgba(45, 51, 62, 0.12); +$border1: rgba(45, 51, 62, 0.30); // Accent colors // ------------------------- -$blue: #1F62E0; +$blue: #F0E4B6; $red: $red-base; $yellow: #ecbb13; $orange: #eb7b18; $purple: #9933cc; -$variable: #1F62E0; +$variable: #F0E4B6; $brand-primary: #eb7b18; -$brand-success: #1B855E; -$brand-warning: #FF9900; +$brand-success: #83D39E; +$brand-warning: #F3D086; $brand-danger: #E0226E; $query-red: #CF0E5B; @@ -93,17 +93,17 @@ $critical: #CF0E5B; // Scaffolding // ------------------------- -$body-bg: #F4F5F5; -$page-bg: #F4F5F5; -$dashboard-bg: #F4F5F5; +$body-bg: #F6F5F3; +$page-bg: #F6F5F3; +$dashboard-bg: #F6F5F3; -$text-color: rgba(36, 41, 46, 1); +$text-color: #2D333E; $text-color-strong: #000000; -$text-color-semi-weak: rgba(36, 41, 46, 0.75); -$text-color-weak: rgba(36, 41, 46, 0.75); -$text-color-faint: rgba(36, 41, 46, 0.64); +$text-color-semi-weak: #2d333e; +$text-color-weak: #2d333e; +$text-color-faint: #9DA7B8; $text-color-emphasis: #000000; -$text-blue: #1F62E0; +$text-blue: #F0E4B6; $text-shadow-faint: none; @@ -113,14 +113,14 @@ $brand-gradient-vertical: linear-gradient(0.01deg, #F53E4C -31.2%, #FF8833 113.0 // Links // ------------------------- -$link-color: rgba(36, 41, 46, 1); -$link-color-disabled: rgba(36, 41, 46, 0.64); +$link-color: #2D333E; +$link-color-disabled: #9DA7B8; $link-hover-color: #000000; -$external-link-color: #1F62E0; +$external-link-color: #F0E4B6; // Typography // ------------------------- -$headings-color: rgba(36, 41, 46, 1); +$headings-color: #2D333E; $abbr-border-color: $gray-2 !default; $text-muted: $text-color-weak; @@ -128,30 +128,30 @@ $hr-border-color: $gray-4 !default; // Panel // ------------------------- -$panel-bg: #FFFFFF; -$panel-border: 1px solid rgba(36, 41, 46, 0.12); -$panel-header-hover-bg: rgba(36, 41, 46, 0.12); +$panel-bg: #FDFDFC; +$panel-border: 1px solid rgba(45, 51, 62, 0.12); +$panel-header-hover-bg: rgba(45, 51, 62, 0.12); $panel-box-shadow: none; $panel-corner: $panel-bg; // Page header -$page-header-bg: #F4F5F5; +$page-header-bg: #F6F5F3; $page-header-shadow: inset 0px -3px 10px $gray-6; -$page-header-border-color: #F4F5F5; +$page-header-border-color: #F6F5F3; $divider-border-color: $gray-2; // Graphite Target Editor -$tight-form-func-bg: #F4F5F5; -$tight-form-func-highlight-bg: #eff0f0; +$tight-form-func-bg: #FDFDFC; +$tight-form-func-highlight-bg: #f9f9f6; -$modal-backdrop-bg: #FFFFFF; +$modal-backdrop-bg: #FDFDFC; $code-tag-bg: $gray-6; $code-tag-border: $gray-4; // cards -$card-background: #F4F5F5; -$card-background-hover: #F4F5F5; +$card-background: #FDFDFC; +$card-background-hover: #FDFDFC; $card-shadow: none; // Lists @@ -168,10 +168,10 @@ $scrollbarBorder: $gray-7; // Tables // ------------------------- -$table-bg-accent: #F4F5F5; -$table-border: rgba(36, 41, 46, 0.30); -$table-bg-odd: rgb(249, 249, 249); -$table-bg-hover: rgb(242, 242, 242); +$table-bg-accent: #FDFDFC; +$table-border: rgba(45, 51, 62, 0.30); +$table-bg-odd: rgb(247, 247, 246); +$table-bg-hover: rgb(240, 240, 239); // Buttons // ------------------------- @@ -207,16 +207,16 @@ $btn-active-box-shadow: 0px 0px 4px rgba(234, 161, 51, 0.6); // Forms // ------------------------- -$input-bg: #FFFFFF; -$input-bg-disabled: rgba(36, 41, 46, 0.04); +$input-bg: #FDFDFC; +$input-bg-disabled: rgba(45, 51, 62, 0.04); -$input-color: rgba(36, 41, 46, 1); -$input-border-color: rgba(36, 41, 46, 0.30); +$input-color: #2D333E; +$input-border-color: rgba(45, 51, 62, 0.30); $input-box-shadow: none; $input-border-focus: #5794f2; $input-box-shadow-focus: #5794f2; -$input-color-placeholder: rgba(36, 41, 46, 0.64); -$input-label-bg: #F4F5F5; +$input-color-placeholder: #9DA7B8; +$input-label-bg: #FDFDFC; $input-color-select-arrow: #7b8087; // search @@ -229,10 +229,10 @@ $typeahead-selected-color: $yellow; // Dropdowns // ------------------------- -$dropdownBackground: #FFFFFF; -$dropdownBorder: rgba(36, 41, 46, 0.12); -$dropdownDividerTop: rgba(36, 41, 46, 0.12); -$dropdownDividerBottom: rgba(36, 41, 46, 0.12); +$dropdownBackground: #FDFDFC; +$dropdownBorder: rgba(45, 51, 62, 0.12); +$dropdownDividerTop: rgba(45, 51, 62, 0.12); +$dropdownDividerBottom: rgba(45, 51, 62, 0.12); $dropdownShadow: 0px 13px 20px 1px rgba(24, 26, 27, 0.18); $dropdownLinkColor: $dark-2; @@ -263,8 +263,8 @@ $side-menu-header-color: #e9edf2; // Menu dropdowns // ------------------------- -$menu-dropdown-bg: #FFFFFF; -$menu-dropdown-hover-bg: rgba(36, 41, 46, 0.12); +$menu-dropdown-bg: #FDFDFC; +$menu-dropdown-hover-bg: rgba(45, 51, 62, 0.12); $menu-dropdown-shadow: 0px 13px 20px 1px rgba(24, 26, 27, 0.18); // Tabs @@ -278,21 +278,21 @@ $error-text-color: #CF0E5B; $success-text-color: #0A764E; $alert-error-bg: #E0226E; -$alert-success-bg: #1B855E; -$alert-warning-bg: #FF9900; -$alert-info-bg: #FF9900; +$alert-success-bg: #83D39E; +$alert-warning-bg: #F3D086; +$alert-info-bg: #F3D086; // Tooltips and popovers -$tooltipBackground: #F4F5F5; -$tooltipColor: rgba(36, 41, 46, 1); -$tooltipArrowColor: #F4F5F5; +$tooltipBackground: #FDFDFC; +$tooltipColor: #2D333E; +$tooltipArrowColor: #FDFDFC; $tooltipBackgroundError: #E0226E; $tooltipShadow: 0px 4px 8px rgba(24, 26, 27, 0.2); -$popover-bg: #FFFFFF; -$popover-color: rgba(36, 41, 46, 1); -$popover-border-color: rgba(36, 41, 46, 0.12); -$popover-header-bg: #F4F5F5; +$popover-bg: #FDFDFC; +$popover-color: #2D333E; +$popover-border-color: rgba(45, 51, 62, 0.12); +$popover-header-bg: #FDFDFC; $popover-shadow: 0px 13px 20px 1px rgba(24, 26, 27, 0.18); $graph-tooltip-bg: $gray-5; @@ -305,7 +305,7 @@ $popover-error-bg: $btn-danger-bg; $popover-help-bg: $tooltipBackground; $popover-help-color: $tooltipColor; -$popover-code-bg: #FFFFFF; +$popover-code-bg: #FDFDFC; $popover-code-boxshadow: 0 0 5px $gray60; // images @@ -334,14 +334,14 @@ $json-explorer-url-color: $blue-base; // Changelog and diff // ------------------------- -$diff-label-bg: rgba(36, 41, 46, 0.12); +$diff-label-bg: rgba(45, 51, 62, 0.12); $diff-label-fg: $gray-2; $diff-arrow-color: $dark-2; -$diff-group-bg: #F4F5F5; +$diff-group-bg: #FDFDFC; -$diff-json-bg: #F4F5F5; -$diff-json-fg: rgba(36, 41, 46, 1); +$diff-json-bg: #FDFDFC; +$diff-json-fg: #2D333E; $diff-json-added: $blue-shade; $diff-json-deleted: $red-shade; diff --git a/public/views/index-microfrontend-template.html b/public/views/index-microfrontend-template.html new file mode 100644 index 0000000000000..a6205f112bad9 --- /dev/null +++ b/public/views/index-microfrontend-template.html @@ -0,0 +1,37 @@ + + + + FluxNinja Microfrontend + + + + + +
+ + + + <% for (index in htmlWebpackPlugin.files.js) { %> <% if (htmlWebpackPlugin.files.jsIntegrity) { %> + + <% } else { %> + + <% } %> <% } %> + + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000..49e7905763277 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +flex==6.14.1 +Jinja2==3.1.2 +loguru==0.6.0 +MarkupSafe==2.1.1 +prance==0.21.8.0 +requests==2.28.1 +typer==0.6.1 diff --git a/scripts/webpack/webpack.common.js b/scripts/webpack/webpack.common.js index 0692e4355acf8..82adc1d17db0f 100644 --- a/scripts/webpack/webpack.common.js +++ b/scripts/webpack/webpack.common.js @@ -1,13 +1,15 @@ const path = require('path'); const webpack = require('webpack'); +const packageName = require('../../package.json').name; + const CorsWorkerPlugin = require('./plugins/CorsWorkerPlugin'); module.exports = { target: 'web', entry: { app: './public/app/index.ts', - swagger: './public/swagger/index.tsx', + fn_dashboard: './public/app/fn_dashboard.ts', }, output: { clean: true, @@ -15,6 +17,9 @@ module.exports = { filename: '[name].[contenthash].js', // Keep publicPath relative for host.com/grafana/ deployments publicPath: 'public/build/', + library: `${packageName}-[name]`, + libraryTarget: 'umd', + chunkLoadingGlobal: `webpackJsonp_${packageName}`, }, resolve: { extensions: ['.ts', '.tsx', '.es6', '.js', '.json', '.svg'], @@ -79,7 +84,7 @@ module.exports = { }, { test: /\.html$/, - exclude: /(index|error)\-template\.html/, + exclude: /(index|error|index-microfrontend)\-template\.html/, use: [ { loader: 'ngtemplate-loader?relativeTo=' + path.resolve(__dirname, '../../public') + '&prefix=public', diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 82accfe50f027..f20e9c0369d33 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -39,6 +39,7 @@ module.exports = (env = {}) => { app: './public/app/index.ts', dark: './public/sass/grafana.dark.scss', light: './public/sass/grafana.light.scss', + fn_dashboard: './public/app/fn_dashboard.ts', }, // If we enabled watch option via CLI @@ -128,6 +129,28 @@ module.exports = (env = {}) => { new MiniCssExtractPlugin({ filename: 'grafana.[name].[contenthash].css', }), + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/views/error.html'), + template: path.resolve(__dirname, '../../public/views/error-template.html'), + inject: false, + chunksSortMode: 'none', + excludeChunks: ['dark', 'light', 'fn_dashboard'], + }), + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/views/index.html'), + template: path.resolve(__dirname, '../../public/views/index-template.html'), + inject: false, + chunksSortMode: 'none', + excludeChunks: ['dark', 'light', 'fn_dashboard'], + }), + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/microfrontends/fn_dashboard/index.html'), + template: path.resolve(__dirname, '../../public/views/index-microfrontend-template.html'), + inject: false, + chunksSortMode: 'none', + excludeChunks: ['dark', 'light', 'app'], + }), + new HTMLWebpackCSSChunks(), new DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development'), diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 98768225963fe..0e3ff4650888d 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -31,8 +31,10 @@ module.exports = (env = {}) => devtool: 'source-map', entry: { + app: './public/app/index.ts', dark: './public/sass/grafana.dark.scss', light: './public/sass/grafana.light.scss', + fn_dashboard: './public/app/fn_dashboard.ts', }, module: { @@ -70,15 +72,29 @@ module.exports = (env = {}) => new MiniCssExtractPlugin({ filename: 'grafana.[name].[contenthash].css', }), - /** - * I know we have two manifest plugins here. - * WebpackManifestPlugin was only used in prod before and does not support integrity hashes - */ - new WebpackAssetsManifest({ - entrypoints: true, - integrity: true, - publicPath: true, + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/views/error.html'), + template: path.resolve(__dirname, '../../public/views/error-template.html'), + inject: false, + excludeChunks: ['dark', 'light', 'fn_dashboard'], + chunksSortMode: 'none', }), + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/views/index.html'), + template: path.resolve(__dirname, '../../public/views/index-template.html'), + inject: false, + excludeChunks: ['manifest', 'dark', 'light', 'fn_dashboard'], + chunksSortMode: 'none', + }), + // Added fn_dashboard/index.html + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/microfrontends/fn_dashboard/index.html'), + template: path.resolve(__dirname, '../../public/views/index-microfrontend-template.html'), + inject: false, + chunksSortMode: 'none', + excludeChunks: ['dark', 'light', 'app'], + }), + new HTMLWebpackCSSChunks(), new WebpackManifestPlugin({ fileName: path.join(process.cwd(), 'manifest.json'), filter: (file) => !file.name.endsWith('.map'), diff --git a/yarn.lock b/yarn.lock index 38872ab3bb0fc..91dc05449cd50 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4939,8 +4939,8 @@ __metadata: linkType: hard "@mapbox/mapbox-gl-style-spec@npm:^13.23.1": - version: 13.25.0 - resolution: "@mapbox/mapbox-gl-style-spec@npm:13.25.0" + version: 13.27.0 + resolution: "@mapbox/mapbox-gl-style-spec@npm:13.27.0" dependencies: "@mapbox/jsonlint-lines-primitives": "npm:~2.0.2" "@mapbox/point-geometry": "npm:^0.1.0" @@ -5155,8 +5155,8 @@ __metadata: linkType: hard "@npmcli/fs@npm:^1.0.0": - version: 1.0.0 - resolution: "@npmcli/fs@npm:1.0.0" + version: 1.1.1 + resolution: "@npmcli/fs@npm:1.1.1" dependencies: "@gar/promisify": "npm:^1.0.1" semver: "npm:^7.3.5" @@ -9033,8 +9033,8 @@ __metadata: linkType: hard "@types/babel__generator@npm:*": - version: 7.6.3 - resolution: "@types/babel__generator@npm:7.6.3" + version: 7.6.4 + resolution: "@types/babel__generator@npm:7.6.4" dependencies: "@babel/types": "npm:^7.0.0" checksum: 10/11a6fb83c3f9eb6ce19eebfd64e1d558aa445ca7c8c6db3e7760ade517b8734a18cf500e238058ca09ae8486a6350e1071f826f38a5a233ccfc5dd2a009340b3 @@ -9068,8 +9068,8 @@ __metadata: linkType: hard "@types/body-parser@npm:*": - version: 1.19.1 - resolution: "@types/body-parser@npm:1.19.1" + version: 1.19.2 + resolution: "@types/body-parser@npm:1.19.2" dependencies: "@types/connect": "npm:*" "@types/node": "npm:*" @@ -9143,8 +9143,8 @@ __metadata: linkType: hard "@types/d3-axis@npm:*": - version: 3.0.1 - resolution: "@types/d3-axis@npm:3.0.1" + version: 3.0.2 + resolution: "@types/d3-axis@npm:3.0.2" dependencies: "@types/d3-selection": "npm:*" checksum: 10/2d321c4f4169d9fdc8a17cca00d1581a2f7e65d7a79f29da055579cc3e9e0809ea28f4578fe2b835d008278ab4e106c694ea4de1da0a35cbe609691537ac2efc @@ -9152,8 +9152,8 @@ __metadata: linkType: hard "@types/d3-brush@npm:*": - version: 3.0.1 - resolution: "@types/d3-brush@npm:3.0.1" + version: 3.0.2 + resolution: "@types/d3-brush@npm:3.0.2" dependencies: "@types/d3-selection": "npm:*" checksum: 10/a77f31cb99d1e00950ab2da9319dad33aea7c0f432ded468070799b24c3839fbb189f2f73562f008b02e5a7c4c5e3f14b4bd1650750223dc6637a6283448ad77 @@ -9175,8 +9175,8 @@ __metadata: linkType: hard "@types/d3-contour@npm:*": - version: 3.0.1 - resolution: "@types/d3-contour@npm:3.0.1" + version: 3.0.2 + resolution: "@types/d3-contour@npm:3.0.2" dependencies: "@types/d3-array": "npm:*" "@types/geojson": "npm:*" @@ -9199,8 +9199,8 @@ __metadata: linkType: hard "@types/d3-drag@npm:*": - version: 3.0.1 - resolution: "@types/d3-drag@npm:3.0.1" + version: 3.0.2 + resolution: "@types/d3-drag@npm:3.0.2" dependencies: "@types/d3-selection": "npm:*" checksum: 10/7bae2779d127fec2d384bab2cbb07c19102a2d51c72093cdd1a815e74448a077822544d3617f3d7fc3b7c0a7a2829693431ba7db03d1ac61662a71b21b2eee5a @@ -9222,8 +9222,8 @@ __metadata: linkType: hard "@types/d3-fetch@npm:*": - version: 3.0.1 - resolution: "@types/d3-fetch@npm:3.0.1" + version: 3.0.2 + resolution: "@types/d3-fetch@npm:3.0.2" dependencies: "@types/d3-dsv": "npm:*" checksum: 10/4369842d970b06079ff43a4c7384e454776b5fef42b445f78021e078413d0cb5b11408f30cdc4db3e674419d1b7cccd178fd70faf5177f8df5ec89ae39f62f53 @@ -9337,8 +9337,8 @@ __metadata: linkType: hard "@types/d3-shape@npm:*": - version: 3.0.2 - resolution: "@types/d3-shape@npm:3.0.2" + version: 3.1.1 + resolution: "@types/d3-shape@npm:3.1.1" dependencies: "@types/d3-path": "npm:*" checksum: 10/43a6b73d539679a5c672fb63f4e7063517c39aad74e30b17aacce1802b3c24207a8d824584164a33d7c2ccae84a774dc9f767ec95e4e38afb7d8b11cee9e3c65 @@ -9383,8 +9383,8 @@ __metadata: linkType: hard "@types/d3-transition@npm:*": - version: 3.0.1 - resolution: "@types/d3-transition@npm:3.0.1" + version: 3.0.3 + resolution: "@types/d3-transition@npm:3.0.3" dependencies: "@types/d3-selection": "npm:*" checksum: 10/2f9d11d40c7560d8cb6163e579bebf5781285589dd9812fb050772ff376250457e715f764f6d3edff0cf91f23df4e23d43cd34b4ca740391d2557628aadfac69 @@ -9392,8 +9392,8 @@ __metadata: linkType: hard "@types/d3-zoom@npm:*": - version: 3.0.1 - resolution: "@types/d3-zoom@npm:3.0.1" + version: 3.0.2 + resolution: "@types/d3-zoom@npm:3.0.2" dependencies: "@types/d3-interpolate": "npm:*" "@types/d3-selection": "npm:*" @@ -11312,7 +11312,7 @@ __metadata: languageName: node linkType: hard -"abbrev@npm:1": +"abbrev@npm:1, abbrev@npm:^1.0.0": version: 1.1.1 resolution: "abbrev@npm:1.1.1" checksum: 10/2d882941183c66aa665118bafdab82b7a177e9add5eb2776c33e960a4f3c89cff88a1b38aba13a456de01d0dd9d66a8bea7c903268b21ea91dd1097e1e2e8243 @@ -13443,6 +13443,13 @@ __metadata: languageName: node linkType: hard +"colors@npm:1.0.3": + version: 1.0.3 + resolution: "colors@npm:1.0.3" + checksum: 234e8d3ab7e4003851cdd6a1f02eaa16dabc502ee5f4dc576ad7959c64b7477b15bd21177bab4055a4c0a66aa3d919753958030445f87c39a253d73b7a3637f5 + languageName: node + linkType: hard + "colors@npm:1.4.0": version: 1.4.0 resolution: "colors@npm:1.4.0" @@ -13934,9 +13941,9 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^7.0.0, cosmiconfig@npm:^7.0.1": - version: 7.0.1 - resolution: "cosmiconfig@npm:7.0.1" +"cosmiconfig@npm:^7, cosmiconfig@npm:^7.0.0, cosmiconfig@npm:^7.0.1": + version: 7.1.0 + resolution: "cosmiconfig@npm:7.1.0" dependencies: "@types/parse-json": "npm:^4.0.0" import-fresh: "npm:^3.2.1" @@ -14213,8 +14220,8 @@ __metadata: linkType: hard "css-select@npm:^4.1.3": - version: 4.1.3 - resolution: "css-select@npm:4.1.3" + version: 4.3.0 + resolution: "css-select@npm:4.3.0" dependencies: boolbase: "npm:^1.0.0" css-what: "npm:^5.0.0" @@ -15171,8 +15178,8 @@ __metadata: linkType: hard "defaults@npm:^1.0.3": - version: 1.0.3 - resolution: "defaults@npm:1.0.3" + version: 1.0.4 + resolution: "defaults@npm:1.0.4" dependencies: clone: "npm:^1.0.2" checksum: 10/96e2112da6553d376afd5265ea7cbdb2a3b45535965d71ab8bb1da10c8126d168fdd5268799625324b368356d21ba2a7b3d4ec50961f11a47b7feb9de3d4413e @@ -15522,9 +15529,9 @@ __metadata: languageName: node linkType: hard -"domhandler@npm:^4.0.0, domhandler@npm:^4.2.0": - version: 4.2.2 - resolution: "domhandler@npm:4.2.2" +"domhandler@npm:^4.0.0, domhandler@npm:^4.2.0, domhandler@npm:^4.3.1": + version: 4.3.1 + resolution: "domhandler@npm:4.3.1" dependencies: domelementtype: "npm:^2.2.0" checksum: 10/502cb297ba7b5a369c944dd2ecde1acd63992929d3f24b2dbd66a65cd6cfc21c5d2f237b0c68d4ec03d4224b1d70b511f04f4423f9aab42777488ee88c98e7e6 @@ -15911,8 +15918,8 @@ __metadata: linkType: hard "error-stack-parser@npm:^2.0.6": - version: 2.0.6 - resolution: "error-stack-parser@npm:2.0.6" + version: 2.1.4 + resolution: "error-stack-parser@npm:2.1.4" dependencies: stackframe: "npm:^1.1.1" checksum: 10/c83a0f425b73ed8bae4b05535f76477fdd4421e2cca398a2051719ac7eb5f918622d6313ef24f6ab6f64cbd38ebd1119bcb15cd792befbf2dd472d02062ff6d8 @@ -17325,8 +17332,8 @@ __metadata: linkType: hard "fb-watchman@npm:^2.0.0": - version: 2.0.1 - resolution: "fb-watchman@npm:2.0.1" + version: 2.0.2 + resolution: "fb-watchman@npm:2.0.2" dependencies: bser: "npm:2.1.1" checksum: 10/9a03efc7d41ce3ca3d799d63505a1f7312caddf4e7737d39f2165bfe4872cbd4b87eccc9e6c57229ea08f14b4d7187896da31a7270b8da7a4aaa8fba2d3d1c42 @@ -17481,7 +17488,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^2.0.0, find-up@npm:^2.1.0": +"find-up@npm:^2.0.0": version: 2.1.0 resolution: "find-up@npm:2.1.0" dependencies: @@ -19146,8 +19153,8 @@ __metadata: linkType: hard "html-minifier-terser@npm:^6.0.2": - version: 6.0.2 - resolution: "html-minifier-terser@npm:6.0.2" + version: 6.1.0 + resolution: "html-minifier-terser@npm:6.1.0" dependencies: camel-case: "npm:^4.1.2" clean-css: "npm:^5.1.5" @@ -19354,8 +19361,8 @@ __metadata: linkType: hard "http-proxy-middleware@npm:^2.0.3": - version: 2.0.4 - resolution: "http-proxy-middleware@npm:2.0.4" + version: 2.0.6 + resolution: "http-proxy-middleware@npm:2.0.6" dependencies: "@types/http-proxy": "npm:^1.17.8" http-proxy: "npm:^1.18.1" @@ -19776,8 +19783,8 @@ __metadata: linkType: hard "intl-messageformat@npm:^10.1.0": - version: 10.1.4 - resolution: "intl-messageformat@npm:10.1.4" + version: 10.2.5 + resolution: "intl-messageformat@npm:10.2.5" dependencies: "@formatjs/ecma402-abstract": "npm:1.12.0" "@formatjs/fast-memoize": "npm:1.2.6" @@ -20204,8 +20211,8 @@ __metadata: linkType: hard "is-number-object@npm:^1.0.4": - version: 1.0.6 - resolution: "is-number-object@npm:1.0.6" + version: 1.0.7 + resolution: "is-number-object@npm:1.0.7" dependencies: has-tostringtag: "npm:^1.0.0" checksum: 10/d848fdc0fc69e30866b87fcaae17a3e68a8be669073ab3bf9a578c29106a2d5084089a2e7bc40819ec55eac94a52d9e20d735e7bfd3a46202b17199e555f91fa @@ -20917,8 +20924,8 @@ __metadata: linkType: hard "jest-pnp-resolver@npm:^1.2.2": - version: 1.2.2 - resolution: "jest-pnp-resolver@npm:1.2.2" + version: 1.2.3 + resolution: "jest-pnp-resolver@npm:1.2.3" peerDependencies: jest-resolve: "*" peerDependenciesMeta: @@ -21597,8 +21604,8 @@ __metadata: linkType: hard "keycon@npm:^1.2.0": - version: 1.2.2 - resolution: "keycon@npm:1.2.2" + version: 1.4.0 + resolution: "keycon@npm:1.4.0" dependencies: "@daybrush/utils": "npm:^1.7.1" "@scena/event-emitter": "npm:^1.0.2" @@ -23619,8 +23626,8 @@ __metadata: linkType: hard "moo-color@npm:^1.0.2": - version: 1.0.2 - resolution: "moo-color@npm:1.0.2" + version: 1.0.3 + resolution: "moo-color@npm:1.0.3" dependencies: color-name: "npm:^1.1.4" checksum: 10/6dced73bfb3048d2a60e4c7e2a5c414c4e7877dac54283168715a891525819109141b40bd9a7fd28f878802b4e166bd0452be926bfb6c0ab95bf9ee2b84e1b3d @@ -24670,7 +24677,7 @@ __metadata: languageName: node linkType: hard -"ora@npm:^5.4.1": +"ora@npm:^5.1.0, ora@npm:^5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" dependencies: @@ -25394,6 +25401,13 @@ __metadata: languageName: node linkType: hard +"pofile@npm:^1.1.0": + version: 1.1.4 + resolution: "pofile@npm:1.1.4" + checksum: 7ef428d2793fcbcf021e4250d36043374ffbd7c8e15268977fae2361536abb894e97ee58525b2c1eeda5688a2b14b274657a271e08816059b12d8c02ac99fde0 + languageName: node + linkType: hard + "polished@npm:^4.2.2": version: 4.2.2 resolution: "polished@npm:4.2.2" @@ -27548,8 +27562,8 @@ __metadata: linkType: hard "react-use-measure@npm:^2.0.4": - version: 2.0.4 - resolution: "react-use-measure@npm:2.0.4" + version: 2.1.1 + resolution: "react-use-measure@npm:2.1.1" dependencies: debounce: "npm:^1.2.0" peerDependencies: @@ -28478,8 +28492,8 @@ __metadata: linkType: hard "rollup-plugin-node-externals@npm:^5.0.0": - version: 5.0.2 - resolution: "rollup-plugin-node-externals@npm:5.0.2" + version: 5.0.3 + resolution: "rollup-plugin-node-externals@npm:5.0.3" peerDependencies: rollup: ^2.60.0 || ^3.0.0 checksum: 10/65d24e6f174d170b855912f230e2dbb9debee4c81d2819e88391f324cc190a84f2c1ab4b421688145786df822434e40b6203524be497832b2f1201dc3728ef77 @@ -28885,7 +28899,7 @@ __metadata: languageName: node linkType: hard -"set-blocking@npm:^2.0.0, set-blocking@npm:~2.0.0": +"set-blocking@npm:^2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" checksum: 10/8980ebf7ae9eb945bb036b6e283c547ee783a1ad557a82babf758a065e2fb6ea337fd82cac30dd565c1e606e423f30024a19fff7afbf4977d784720c4026a8ef @@ -29719,8 +29733,8 @@ __metadata: linkType: hard "stack-generator@npm:^2.0.5": - version: 2.0.5 - resolution: "stack-generator@npm:2.0.5" + version: 2.0.10 + resolution: "stack-generator@npm:2.0.10" dependencies: stackframe: "npm:^1.1.1" checksum: 10/3c7b925c34b93f1528e334f1ed5fe4d7a5d4874589cb63ce539f569e9c76649037b7848be953b24f3c46865584425281fc51925e42c87b7fec128ad646ccae97 @@ -29737,8 +29751,8 @@ __metadata: linkType: hard "stack-utils@npm:^2.0.3": - version: 2.0.5 - resolution: "stack-utils@npm:2.0.5" + version: 2.0.6 + resolution: "stack-utils@npm:2.0.6" dependencies: escape-string-regexp: "npm:^2.0.0" checksum: 10/a6d64e5dd24d321289ebefdff2e210ece75fdf20dbcdb702b86da1f7b730743fae3e9337adae4a5cc00d4970d748ff758387df3ea7c71c45b466c43c7359bc00 @@ -29760,8 +29774,8 @@ __metadata: linkType: hard "stacktrace-gps@npm:^3.0.4": - version: 3.0.4 - resolution: "stacktrace-gps@npm:3.0.4" + version: 3.1.2 + resolution: "stacktrace-gps@npm:3.1.2" dependencies: source-map: "npm:0.5.6" stackframe: "npm:^1.1.1" From d0f46918052d4bfa3dd3bac429982754a54c5b50 Mon Sep 17 00:00:00 2001 From: Krzysztof Kwapisiewicz Date: Tue, 3 Jan 2023 14:47:02 +0100 Subject: [PATCH 006/101] Run `go mod tidy` --- go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/go.mod b/go.mod index ae56f3f9e7f60..3e5f9a1b72aaa 100644 --- a/go.mod +++ b/go.mod @@ -500,6 +500,7 @@ replace xorm.io/xorm => github.com/grafana/grafana/pkg/util/xorm v0.0.1 // lock for mysql tsdb compat replace github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.7.1 replace google.golang.org/genproto => google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 + // This is for sending custom HTTP headers in druid client. // Change in upstream: https://github.com/grafadruid/go-druid/pull/71 replace github.com/grafadruid/go-druid => github.com/fluxninja/go-druid v0.0.0-20220825112309-14a37dd3317d From 1c481356185106f3f0cd5630ece38b693ebf2acc Mon Sep 17 00:00:00 2001 From: Krzysztof Kwapisiewicz Date: Tue, 3 Jan 2023 14:50:54 +0100 Subject: [PATCH 007/101] Fix druid plugin registration --- pkg/plugins/backendplugin/coreplugin/registry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/plugins/backendplugin/coreplugin/registry.go b/pkg/plugins/backendplugin/coreplugin/registry.go index 4c06863de1bbf..a65ce81905f8d 100644 --- a/pkg/plugins/backendplugin/coreplugin/registry.go +++ b/pkg/plugins/backendplugin/coreplugin/registry.go @@ -108,7 +108,6 @@ func ProvideCoreRegistry(tracer tracing.Tracer, am *azuremonitor.Service, cw *cl InfluxDB: asBackendPlugin(idb), Loki: asBackendPlugin(lk), OpenTSDB: asBackendPlugin(otsdb), - Druid: asBackendPlugin(dr), Prometheus: asBackendPlugin(pr), Tempo: asBackendPlugin(t), TestData: asBackendPlugin(td), @@ -118,6 +117,7 @@ func ProvideCoreRegistry(tracer tracing.Tracer, am *azuremonitor.Service, cw *cl Grafana: asBackendPlugin(graf), Pyroscope: asBackendPlugin(pyroscope), Parca: asBackendPlugin(parca), + Druid: asBackendPlugin(dr), }) } From ded51d2c1fc33e07e365184542415a7b3d5da98a Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Tue, 3 Jan 2023 14:56:27 +0100 Subject: [PATCH 008/101] FN FluxNinja changes --- .../dashboard/containers/DashboardPage.tsx | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index 74ad5e5aedd3e..15d81aea670c4 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -183,7 +183,7 @@ export class UnthemedDashboardPage extends PureComponent { } initDashboard() { - const { dashboard, isPublic, isFNDashboard, match, queryParams } = this.props; + const { dashboard, isPublic, match, queryParams, isFNDashboard } = this.props; if (dashboard) { this.closeDashboard(); @@ -214,14 +214,15 @@ export class UnthemedDashboardPage extends PureComponent { } if (!isPublic && !isFNDashboard) { - if ( - prevProps.match.params.uid !== match.params.uid || - (routeReloadCounter !== undefined && this.forceRouteReloadCounter !== routeReloadCounter) - ) { - this.initDashboard(); - this.forceRouteReloadCounter = routeReloadCounter; - return; - }} + if ( + prevProps.match.params.uid !== match.params.uid || + (routeReloadCounter !== undefined && this.forceRouteReloadCounter !== routeReloadCounter) + ) { + this.initDashboard(); + this.forceRouteReloadCounter = routeReloadCounter; + return; + } + } if (prevProps.location.search !== this.props.location.search) { const prevUrlParams = prevProps.queryParams; @@ -389,12 +390,12 @@ export class UnthemedDashboardPage extends PureComponent { }; render() { - const { dashboard, initError, queryParams, isPublic , isFNDashboard, fnLoader} = this.props; + const { dashboard, initError, queryParams, isPublic, isFNDashboard, fnLoader } = this.props; const { editPanel, viewPanel, updateScrollTop, pageNav, sectionNav } = this.state; const kioskMode = !isPublic ? getKioskMode(this.props.queryParams) : KioskMode.Full; if (!dashboard || !pageNav || !sectionNav) { - return fnLoader ? <>{fnLoader} :; + return fnLoader ? <>{fnLoader} : ; } const inspectPanel = this.getInspectPanel(); @@ -478,22 +479,27 @@ export class UnthemedDashboardPage extends PureComponent { navModel={sectionNav} pageNav={pageNav} layout={PageLayoutType.Canvas} - toolbar={ - this.props.controlsContainer ? ( - {toolbar} - ) : ( - toolbar - ) - } + toolbar={ + this.props.controlsContainer ? ( + {toolbar} + ) : ( + toolbar + ) + } className={pageClassName} onSetScrollRef={this.setScrollRef} > - {!isFNDashboard && } + {!isFNDashboard && } {initError && } {showSubMenu && (
- +
)} {config.featureToggles.angularDeprecationUI && dashboard.hasAngularPlugins() && dashboard.uid !== null && ( @@ -541,9 +547,9 @@ export class UnthemedDashboardPage extends PureComponent { } function updateStatePageNavFromProps(props: Props, state: State): State { - const { dashboard, navIndex } = props; + const { dashboard, isFNDashboard } = props; - if (!dashboard) { + if (!dashboard || isFNDashboard) { return state; } From f4da5d33e013a7a819af0713efab19e2fae184a5 Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Tue, 3 Jan 2023 15:17:44 +0100 Subject: [PATCH 009/101] FN FluxNinja changes --- .../dashboard/dashgrid/PanelStateWrapper.tsx | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx b/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx index 5487e6d9fcef0..2448f85dd3dc4 100644 --- a/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx +++ b/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx @@ -27,7 +27,7 @@ import { RefreshEvent } from '@grafana/runtime'; import { VizLegendOptions } from '@grafana/schema'; import { ErrorBoundary, - PanelChrome, + PanelChrome as Panel, PanelContext, PanelContextProvider, SeriesVisibilityChangeMode, @@ -90,7 +90,6 @@ const FN_TITLE_STYLE: CSSProperties = { textTransform: 'capitalize', }; - export class PanelStateWrapper extends PureComponent { private readonly timeSrv: TimeSrv = getTimeSrv(); private subs = new Subscription(); @@ -588,7 +587,7 @@ export class PanelStateWrapper extends PureComponent { if (config.featureToggles.newPanelChromeUI) { return ( - + {(innerWidth, innerHeight) => ( <> { )} - + ); } else { return ( @@ -613,21 +612,23 @@ export class PanelStateWrapper extends PureComponent { className={containerClassNames} aria-label={selectors.components.Panels.Panel.containerByTitle(panel.title)} > - {FNDashboard ? ( - // TODO: Avoid divology. Use HTML5, i.e. wrap texts with p or h element instead of div. -
{panel.title}
- ) : } + {FNDashboard ? ( + // TODO: Avoid divology. Use HTML5, i.e. wrap texts with p or h element instead of div. +
{panel.title}
+ ) : ( + + )} { return { ...state.fnGlobalState }; }; const connector = connect(mapStateToProps); -export const PanelChrome = connector(PanelChromeUnconnected); +export const PanelChrome = connector(PanelStateWrapper); From 6c5d70cbf92e479b78fa1f95278cace1184234cb Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Mon, 28 Nov 2022 14:43:42 -0500 Subject: [PATCH 010/101] Build: Streamline and sync dockerfiles (#58101) * streamline and sync dockerfiles * improve go dependency cacheability * unify alpine and ubuntu Dockerfiles * include glibc support in locally-built alpine images --- .github/pr-commands.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pr-commands.json b/.github/pr-commands.json index fa5dd96fd953a..dc9d783a9d61e 100644 --- a/.github/pr-commands.json +++ b/.github/pr-commands.json @@ -437,4 +437,4 @@ "action": "updateLabel", "addLabel": "area/panel/table" } -] \ No newline at end of file +] From e014d608e4efcbeadcb5d2db51fbdb67e0ff5b8d Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Wed, 4 Jan 2023 12:22:24 +0100 Subject: [PATCH 011/101] FN Remove internationalization provider --- .../dashboard/containers/DashboardPage.tsx | 3 ++- public/app/fn-app/create-mfe.ts | 15 ++++++++++----- public/app/fn-app/fn-app-provider.tsx | 15 +++++++-------- public/app/fn_app.ts | 3 +++ 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index 15d81aea670c4..0d8ac501fc329 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -207,13 +207,14 @@ export class UnthemedDashboardPage extends PureComponent { componentDidUpdate(prevProps: Props, prevState: State) { const { dashboard, match, templateVarsChangedInUrl, isPublic, isFNDashboard } = this.props; - const routeReloadCounter = (this.props.history.location.state as any)?.routeReloadCounter; if (!dashboard) { return; } if (!isPublic && !isFNDashboard) { + const routeReloadCounter = (this.props.history.location?.state as any)?.routeReloadCounter; + if ( prevProps.match.params.uid !== match.params.uid || (routeReloadCounter !== undefined && this.forceRouteReloadCounter !== routeReloadCounter) diff --git a/public/app/fn-app/create-mfe.ts b/public/app/fn-app/create-mfe.ts index d93b754c62473..4dc4be53a45ac 100644 --- a/public/app/fn-app/create-mfe.ts +++ b/public/app/fn-app/create-mfe.ts @@ -195,14 +195,18 @@ class createMfe { static mountFnApp(Component: ComponentType) { const lifeCycleFn: FrameworkLifeCycles['mount'] = (props: FNDashboardProps) => { - return new Promise((res, rej) => { - createMfe.logger('Trying to mount grafana...'); + createMfe.logger('Trying to mount grafana...'); + return new Promise((res, rej) => { try { createMfe.loadFnTheme(props.mode); createMfe.Component = Component; - createMfe.renderMfeComponent(props, () => res(true)); + createMfe.renderMfeComponent(props, () => { + createMfe.logger('Mounted grafana.'); + + return res(true); + }); } catch (err) { const message = `[FN Grafana]: Failed to mount grafana. ${err}`; @@ -286,9 +290,10 @@ class createMfe { * Then we should keep the current props that are read them from the state. */ const mergedProps = merge({}, fnGlobalState, props) as FNDashboardProps; + const container = createMfe.getContainer(mergedProps) - ReactDOM.render(React.createElement(createMfe.Component, mergedProps), createMfe.getContainer(mergedProps), () => { - createMfe.logger('Successfully rendered mfe component.'); + ReactDOM.render(React.createElement(createMfe.Component, mergedProps), container, () => { + createMfe.logger('Rendered mfe component.', {mergedProps, container}); onSuccess(); }); } diff --git a/public/app/fn-app/fn-app-provider.tsx b/public/app/fn-app/fn-app-provider.tsx index fb3df50621b9a..444a33577abd5 100644 --- a/public/app/fn-app/fn-app-provider.tsx +++ b/public/app/fn-app/fn-app-provider.tsx @@ -5,7 +5,6 @@ import { BrowserRouter } from 'react-router-dom'; import { config, navigationLogger } from '@grafana/runtime'; import { ErrorBoundaryAlert, GlobalStyles } from '@grafana/ui'; import { loadAndInitAngularIfEnabled } from 'app/angular/loadAndInitAngularIfEnabled'; -import { I18nProvider } from 'app/core/internationalization'; import { ThemeProvider } from 'app/core/utils/ConfigProvider'; import { store } from 'app/store/store'; @@ -25,7 +24,7 @@ export const FnAppProvider: FC = (props) => { loadAndInitAngularIfEnabled() .then(() => { setReady(true); - $('.preloader').remove(); + // $('.preloader').remove(); }) .catch((err) => console.error(err)); return () => {}; @@ -48,16 +47,16 @@ export const FnAppProvider: FC = (props) => { return ( - - - - {children} - + + + {children || null} + } + /> - ); diff --git a/public/app/fn_app.ts b/public/app/fn_app.ts index a6aa02a6b79bb..37054857c68d5 100644 --- a/public/app/fn_app.ts +++ b/public/app/fn_app.ts @@ -53,6 +53,7 @@ import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend import { RudderstackBackend } from './core/services/echo/backends/analytics/RudderstackBackend'; import { GrafanaJavascriptAgentBackend } from './core/services/echo/backends/grafana-javascript-agent/GrafanaJavascriptAgentBackend'; import { SentryEchoBackend } from './core/services/echo/backends/sentry/SentryBackend'; +import { initializeI18n } from './core/internationalization'; import { initDevFeatures } from './dev'; import { getTimeSrv } from './features/dashboard/services/TimeSrv'; import { PanelDataErrorView } from './features/panel/components/PanelDataErrorView'; @@ -106,6 +107,8 @@ export class GrafanaApp { config.datasources = settings.datasources; config.defaultDatasource = settings.defaultDatasource; + initializeI18n(config.bootData.user.locale); + initEchoSrv(); addClassIfNoOverlayScrollbar(); setLocale(config.bootData.user.locale); From 85f9ab8e9835d09e361ec89a4960c757937404d4 Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Thu, 5 Jan 2023 13:39:55 +0100 Subject: [PATCH 012/101] FN Update sankey panel (30b5be0b5bf03ee8c7) --- public/app/plugins/panel/sankey-panel-0.5.0/module.js | 2 +- .../plugins/panel/sankey-panel-0.5.0/module.js.map | 2 +- .../app/plugins/panel/sankey-panel-0.5.0/plugin.json | 11 +++-------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/module.js b/public/app/plugins/panel/sankey-panel-0.5.0/module.js index 40c143eb0ffc3..9b8245b79e190 100644 --- a/public/app/plugins/panel/sankey-panel-0.5.0/module.js +++ b/public/app/plugins/panel/sankey-panel-0.5.0/module.js @@ -1,3 +1,3 @@ /*! For license information please see module.js.LICENSE.txt */ -define(["react","d3","@grafana/data","@grafana/ui"],(function(t,e,n,r){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=5)}([function(e,n){e.exports=t},function(t,n){t.exports=e},function(t,e){t.exports=n},function(t,e){t.exports=r},,function(t,e,n){"use strict";n.r(e);var r={};n.r(r),n.d(r,"sankey",(function(){return M})),n.d(r,"sankeyCenter",(function(){return v})),n.d(r,"sankeyLeft",(function(){return y})),n.d(r,"sankeyRight",(function(){return p})),n.d(r,"sankeyJustify",(function(){return _})),n.d(r,"sankeyLinkHorizontal",(function(){return F}));var o=n(2);var i=function(){return(i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=i.next()).done;)a.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a}var u=n(0),l=n.n(u),c=n(1);function f(t,e){let n=0;if(void 0===e)for(let e of t)(e=+e)&&(n+=e);else{let r=-1;for(let o of t)(o=+e(o,++r,t))&&(n+=o)}return n}function h(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n=e)&&(n=e);else{let r=-1;for(let o of t)null!=(o=e(o,++r,t))&&(n=o)&&(n=o)}return n}function d(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n>e||void 0===n&&e>=e)&&(n=e);else{let r=-1;for(let o of t)null!=(o=e(o,++r,t))&&(n>o||void 0===n&&o>=o)&&(n=o)}return n}function g(t){return t.target.depth}function y(t){return t.depth}function p(t,e){return e-1-t.height}function _(t,e){return t.sourceLinks.length?t.depth:e-1}function v(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?d(t.sourceLinks,g)-1:0}function k(t){return function(){return t}}function m(t,e){return x(t.source,e.source)||t.index-e.index}function b(t,e){return x(t.target,e.target)||t.index-e.index}function x(t,e){return t.y0-e.y0}function w(t){return t.value}function S(t){return t.index}function L(t){return t.nodes}function A(t){return t.links}function O(t,e){const n=t.get(e);if(!n)throw new Error("missing: "+e);return n}function j({nodes:t}){for(const e of t){let t=e.y0,n=t;for(const n of e.sourceLinks)n.y0=t+n.width/2,t+=n.width;for(const t of e.targetLinks)t.y1=n+t.width/2,n+=t.width}}function M(){let t,e,n,r=0,o=0,i=1,a=1,s=24,u=8,l=S,c=_,g=L,y=A,p=6;function v(){const t={nodes:g.apply(null,arguments),links:y.apply(null,arguments)};return M(t),T(t),P(t),C(t),V(t),j(t),t}function M({nodes:t,links:e}){for(const[e,n]of t.entries())n.index=e,n.sourceLinks=[],n.targetLinks=[];const r=new Map(t.map((e,n)=>[l(e,n,t),e]));for(const[t,n]of e.entries()){n.index=t;let{source:e,target:o}=n;"object"!=typeof e&&(e=n.source=O(r,e)),"object"!=typeof o&&(o=n.target=O(r,o)),e.sourceLinks.push(n),o.targetLinks.push(n)}if(null!=n)for(const{sourceLinks:e,targetLinks:r}of t)e.sort(n),r.sort(n)}function T({nodes:t}){for(const e of t)e.value=void 0===e.fixedValue?Math.max(f(e.sourceLinks,w),f(e.targetLinks,w)):e.fixedValue}function P({nodes:t}){const e=t.length;let n=new Set(t),r=new Set,o=0;for(;n.size;){for(const t of n){t.depth=o;for(const{target:e}of t.sourceLinks)r.add(e)}if(++o>e)throw new Error("circular link");n=r,r=new Set}}function C({nodes:t}){const e=t.length;let n=new Set(t),r=new Set,o=0;for(;n.size;){for(const t of n){t.height=o;for(const{source:e}of t.targetLinks)r.add(e)}if(++o>e)throw new Error("circular link");n=r,r=new Set}}function V(n){const l=function({nodes:t}){const n=h(t,t=>t.depth)+1,o=(i-r-s)/(n-1),a=new Array(n);for(const e of t){const t=Math.max(0,Math.min(n-1,Math.floor(c.call(null,e,n))));e.layer=t,e.x0=r+t*o,e.x1=e.x0+s,a[t]?a[t].push(e):a[t]=[e]}if(e)for(const t of a)t.sort(e);return a}(n);t=Math.min(u,(a-o)/(h(l,t=>t.length)-1)),function(e){const n=d(e,e=>(a-o-(e.length-1)*t)/f(e,w));for(const r of e){let e=o;for(const o of r){o.y0=e,o.y1=e+o.value*n,e=o.y1+t;for(const t of o.sourceLinks)t.width=t.value*n}e=(a-e+t)/(r.length+1);for(let t=0;t0))continue;let o=(e/r-t.y0)*n;t.y0+=o,t.y1+=o,G(t)}void 0===e&&i.sort(x),N(i,r)}}function B(t,n,r){for(let o=t.length-2;o>=0;--o){const i=t[o];for(const t of i){let e=0,r=0;for(const{target:n,value:o}of t.sourceLinks){let i=o*(n.layer-t.layer);e+=J(t,n)*i,r+=i}if(!(r>0))continue;let o=(e/r-t.y0)*n;t.y0+=o,t.y1+=o,G(t)}void 0===e&&i.sort(x),N(i,r)}}function N(e,n){const r=e.length>>1,i=e[r];z(e,i.y0-t,r-1,n),H(e,i.y1+t,r+1,n),z(e,a,e.length-1,n),H(e,o,0,n)}function H(e,n,r,o){for(;r1e-6&&(i.y0+=a,i.y1+=a),n=i.y1+t}}function z(e,n,r,o){for(;r>=0;--r){const i=e[r],a=(i.y1-n)*o;a>1e-6&&(i.y0-=a,i.y1-=a),n=i.y0-t}}function G({sourceLinks:t,targetLinks:e}){if(void 0===n){for(const{source:{sourceLinks:t}}of e)t.sort(b);for(const{target:{targetLinks:e}}of t)e.sort(m)}}function I(t){if(void 0===n)for(const{sourceLinks:e,targetLinks:n}of t)e.sort(b),n.sort(m)}function D(e,n){let r=e.y0-(e.sourceLinks.length-1)*t/2;for(const{target:o,width:i}of e.sourceLinks){if(o===n)break;r+=i+t}for(const{source:t,width:o}of n.targetLinks){if(t===e)break;r-=o}return r}function J(e,n){let r=n.y0-(n.targetLinks.length-1)*t/2;for(const{source:o,width:i}of n.targetLinks){if(o===e)break;r+=i+t}for(const{target:t,width:o}of e.sourceLinks){if(t===n)break;r-=o}return r}return v.update=function(t){return j(t),t},v.nodeId=function(t){return arguments.length?(l="function"==typeof t?t:k(t),v):l},v.nodeAlign=function(t){return arguments.length?(c="function"==typeof t?t:k(t),v):c},v.nodeSort=function(t){return arguments.length?(e=t,v):e},v.nodeWidth=function(t){return arguments.length?(s=+t,v):s},v.nodePadding=function(e){return arguments.length?(u=t=+e,v):u},v.nodes=function(t){return arguments.length?(g="function"==typeof t?t:k(t),v):g},v.links=function(t){return arguments.length?(y="function"==typeof t?t:k(t),v):y},v.linkSort=function(t){return arguments.length?(n=t,v):n},v.size=function(t){return arguments.length?(r=o=0,i=+t[0],a=+t[1],v):[i-r,a-o]},v.extent=function(t){return arguments.length?(r=+t[0][0],i=+t[1][0],o=+t[0][1],a=+t[1][1],v):[[r,o],[i,a]]},v.iterations=function(t){return arguments.length?(p=+t,v):p},v}var T=Math.PI,P=2*T,C=P-1e-6;function V(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function E(){return new V}V.prototype=E.prototype={constructor:V,moveTo:function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},quadraticCurveTo:function(t,e,n,r){this._+="Q"+ +t+","+ +e+","+(this._x1=+n)+","+(this._y1=+r)},bezierCurveTo:function(t,e,n,r,o,i){this._+="C"+ +t+","+ +e+","+ +n+","+ +r+","+(this._x1=+o)+","+(this._y1=+i)},arcTo:function(t,e,n,r,o){t=+t,e=+e,n=+n,r=+r,o=+o;var i=this._x1,a=this._y1,s=n-t,u=r-e,l=i-t,c=a-e,f=l*l+c*c;if(o<0)throw new Error("negative radius: "+o);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(f>1e-6)if(Math.abs(c*s-u*l)>1e-6&&o){var h=n-i,d=r-a,g=s*s+u*u,y=h*h+d*d,p=Math.sqrt(g),_=Math.sqrt(f),v=o*Math.tan((T-Math.acos((g+f-y)/(2*p*_)))/2),k=v/_,m=v/p;Math.abs(k-1)>1e-6&&(this._+="L"+(t+k*l)+","+(e+k*c)),this._+="A"+o+","+o+",0,0,"+ +(c*h>l*d)+","+(this._x1=t+m*s)+","+(this._y1=e+m*u)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,r,o,i){t=+t,e=+e,i=!!i;var a=(n=+n)*Math.cos(r),s=n*Math.sin(r),u=t+a,l=e+s,c=1^i,f=i?r-o:o-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+u+","+l:(Math.abs(this._x1-u)>1e-6||Math.abs(this._y1-l)>1e-6)&&(this._+="L"+u+","+l),n&&(f<0&&(f=f%P+P),f>C?this._+="A"+n+","+n+",0,1,"+c+","+(t-a)+","+(e-s)+"A"+n+","+n+",0,1,"+c+","+(this._x1=u)+","+(this._y1=l):f>1e-6&&(this._+="A"+n+","+n+",0,"+ +(f>=T)+","+c+","+(this._x1=t+n*Math.cos(o))+","+(this._y1=e+n*Math.sin(o))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var B=E,N=Array.prototype.slice,H=function(t){return function(){return t}};function z(t){return t[0]}function G(t){return t[1]}function I(t){return t.source}function D(t){return t.target}function J(t){var e=I,n=D,r=z,o=G,i=null;function a(){var a,s=N.call(arguments),u=e.apply(this,s),l=n.apply(this,s);if(i||(i=a=B()),t(i,+r.apply(this,(s[0]=u,s)),+o.apply(this,s),+r.apply(this,(s[0]=l,s)),+o.apply(this,s)),a)return i=null,a+""||null}return a.source=function(t){return arguments.length?(e=t,a):e},a.target=function(t){return arguments.length?(n=t,a):n},a.x=function(t){return arguments.length?(r="function"==typeof t?t:H(+t),a):r},a.y=function(t){return arguments.length?(o="function"==typeof t?t:H(+t),a):o},a.context=function(t){return arguments.length?(i=null==t?null:t,a):i},a}function R(t,e,n,r,o){t.moveTo(e,n),t.bezierCurveTo(e=(e+r)/2,n,e,o,r,o)}function W(t){return[t.source.x1,t.y0]}function q(t){return[t.target.x0,t.y1]}var F=function(){return J(R).source(W).target(q)};function U(t,e){for(var n=0;n0&&this._data.links.length>0}},{key:"_setLinkGradient",value:function(){var t=this,e=this._svgLink.append("linearGradient").attr("id",(function(t){return t.uid="link-".concat(t.index,"-").concat(Math.random())})).attr("gradientUnits","userSpaceOnUse").attr("x1",(function(t){return t.source.x1})).attr("x2",(function(t){return t.target.x0}));e.append("stop").attr("offset","0%").attr("stop-color",(function(e){return t._color(e.source)})),e.append("stop").attr("offset","100%").attr("stop-color",(function(e){return t._color(e.target)}))}},{key:"_setLinkStroke",value:function(t){switch(this._edgeColor){case X:return"#aaa";case Y:return"url(#".concat(t.uid,")");case $:return this._color(t.source);case tt:return this._color(t.target);default:return}}},{key:"_showLinks",value:function(t){var e=[];[{linkType:"sourceLinks",nodeType:"target"},{linkType:"targetLinks",nodeType:"source"}].forEach((function(n){t[n.linkType].forEach((function(t){e.push(t[n.nodeType])}))})),this._gBound.selectAll(".sankey-node").style("opacity",(function(n){return t.name===n.name||e.find((function(t){return t.name===n.name}))?"1":"0.2"})),this._gBound.selectAll(".sankey-link").style("opacity",(function(e){return!e||e.source.name!==t.name&&e.target.name!==t.name?"0.2":"1"}))}},{key:"_showAll",value:function(){this._gBound.selectAll(".sankey-node").style("opacity","1"),this._gBound.selectAll(".sankey-link").style("opacity","1")}},{key:"_formatValue",value:function(t){return c.format(".2~f")(t)}},{key:"_formatPercent",value:function(t){return c.format(".2~%")(t)}},{key:"_formatThousand",value:function(t){return c.format(".3~s")(t)}},{key:"_labelNode",value:function(t){var e=this._nodes.filter((function(e){return e.depth===t.depth})),n=c.sum(e,(function(t){return t.value})),r=this._formatThousand(t.value),o=this._formatPercent(t.value/n),i=t.name;switch(this._displayValues){case Z:i="".concat(i,"\n ").concat(r);break;case Q:i="".concat(i,"\n ").concat(o);break;case K:i="".concat(i,"\n ").concat(o," - ").concat(r)}return i}},{key:"_renderSVG",value:function(){var t=this;this._container.style("background-color",this._background),this._gBound=this._container.append("g").attr("transform","translate(".concat(this._marginLeft,", ").concat(this._marginTop,")")),this._svgNode=this._gBound.append("g").attr("stroke","#000").selectAll(".sankey-node").data(this._nodes,(function(t){return t.name})).join("rect").attr("class","sankey-node").attr("id",(function(t){return t.name})).attr("x",(function(t){return t.x0})).attr("y",(function(t){return t.y0})).attr("rx",2).attr("ry",2).attr("height",(function(t){return t.y1-t.y0})).attr("width",(function(t){return t.x1-t.x0})).attr("stroke",(function(e){var n=JSON.parse(t._colorArray);return Object.keys(n).includes(e.name)?n[e.name]:"rgba(148, 153, 168, 1)"})).attr("fill",(function(e){var n=JSON.parse(t._colorArray);return Object.keys(n).includes(e.name)?n[e.name]:"rgba(148, 153, 168, 1)"})).on("mouseover",(function(e){return t._highlightOnHover&&t._showLinks(e)})).on("mouseout",(function(e){return t._highlightOnHover&&t._showAll()})),this._svgLink=this._gBound.append("g").attr("fill","none").attr("stroke-opacity",.3).selectAll("g").data(this._links,(function(t){return"".concat(t.source.name,"-").concat(t.target.name)})).join("g").style("mix-blend-mode","multiply"),"path"===this._edgeColor&&this._setLinkGradient(),this._svgLink.append("path").attr("class","sankey-link").attr("d",F()).attr("stroke","rgba(182, 185, 196, 1)").attr("stroke-width",(function(t){return Math.max(1,t.width)})),this._gBound.append("g").attr("font-family","sans-serif").attr("font-size",10).selectAll("text").data(this._nodes).join("text").attr("x",(function(t){return t.x0+8})).attr("y",(function(t){return(t.y1+t.y0)/2})).attr("dy","0.35em").text((function(e){return t._labelNode(e)})),this._gBound.append("g").attr("font-family","sans-serif").attr("font-size",10).selectAll("text").data(this._nodes).join("text").attr("x",(function(t){return t.x0+8})).attr("font-size",14).attr("font-weight","700").attr("y",(function(t){return(t.y1+t.y0)/2+16})).attr("dy","0.35em").text((function(e){return t._formatValue(e.value)})),this._svgNode.append("title").text((function(e){return"".concat(e.name,"\n").concat(t._formatValue(e.value))})),this._svgLink.append("title").text((function(e){return"".concat(e.source.name," → ").concat(e.target.name,"\n").concat(t._formatValue(e.value))}))}},{key:"data",value:function(t){return arguments.length?(this._data=t,this):this._data}},{key:"width",value:function(t){return arguments.length?(this._width=+t,this):this._width}},{key:"height",value:function(t){return arguments.length?(this._height=+t,this):this._height}},{key:"align",value:function(t){return arguments.length?(this._sankeyAlignType=t,this):this._sankeyAlignType}},{key:"colorScheme",value:function(t){return arguments.length?(this._colorScheme=t,this):this._colorScheme}},{key:"colorArray",value:function(t){return arguments.length?(this._colorArray=t,this):this._colorArray}},{key:"edgeColor",value:function(t){return arguments.length?(this._edgeColor=t,this):this._edgeColor}},{key:"displayValues",value:function(t){return arguments.length?(this._displayValues=t,this):this._displayValues}},{key:"highlightOnHover",value:function(t){return arguments.length?(this._highlightOnHover=t,this):this._highlightOnHover}},{key:"render",value:function(){return this._validate()&&(this._init(),this._renderSVG()),this}}])&&U(e.prototype,n),o&&U(e,o),t}(),nt=n(3),rt=function(t){var e=t.message;return l.a.createElement("p",{style:ot},l.a.createElement("div",{style:it},l.a.createElement(nt.Icon,{name:"exclamation-triangle"}),l.a.createElement("div",{style:at},e)))},ot={height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},it={padding:"15px 20px",marginBottom:"4px",position:"relative",color:"rgb(255, 255, 255)",textShadow:"rgb(0 0 0 / 20%) 0px 1px 0px",borderRadius:"3px",display:"flex",flexDirection:"row",alignItems:"center",background:"linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))"},at={marginLeft:10},st=function(t){var e=t.options,n=t.data,r=t.width,o=t.height,i={source:"source",target:"target",value:"value"},a="Required fields not present: "+Object.keys(i).join(", "),f=s(Object(u.useState)({isError:!1,message:""}),2),h=f[0],d=f[1],g=s(Object(u.useState)({nodes:[],links:[]}),2),y=g[0],p=g[1];Object(u.useEffect)((function(){n.error?d({isError:!0,message:n.error.message}):p(_())}),[n]);var _=function(){var t=n.series[0],e=t.fields.find((function(t){return t.name===i.source})),r=t.fields.find((function(t){return t.name===i.target})),o=t.fields.find((function(t){return t.name===i.value})),s=null==e?void 0:e.values.toArray(),u=null==r?void 0:r.values.toArray(),l=null==o?void 0:o.values.toArray();if(function(t,e,n){var r=!0;if(!(t&&e&&n))return d({isError:!0,message:a}),!1;var o=t.every((function(t){return"string"==typeof t})),i=e.every((function(t){return"string"==typeof t})),s=n.every((function(t){return"number"==typeof t}));return o&&i&&s?(d({}),r):(d({isError:!0,message:"Fields should have the following types: source (string), target (string), value (numeric)"}),!1)}(s,u,l)){var f=c.zip(s,u,l);return{nodes:Array.from(new Set(s.concat(u))).map((function(t){return{name:t}})),links:f.map((function(t){return{source:t[0],target:t[1],value:+t[2].toFixed(2)}}))}}},v=function(t){var n=new et(t).width(r).height(o).align(e.align).edgeColor(e.edgeColor).colorScheme(e.colorScheme).displayValues(e.displayValues).highlightOnHover(e.highlightOnHover).data(y);try{n.render()}catch(t){d({isError:!0,message:t.message})}};return h.isError?l.a.createElement(rt,{message:h.message}):l.a.createElement("svg",{viewBox:"0 0 "+r+" "+o,ref:function(t){c.select(t).selectAll("*").remove(),c.select(t).call(v)}})};function ut(){return function(t){var e=t.series,n=a(t,["series"]),r=e.map((function(t){return Object(o.toDataFrame)(i(i({},t),{fields:t.fields.map((function(t,e,n){var r,a=lt.includes(t.name),s=t.values instanceof o.ArrayVector||"function"==typeof(null===(r=t.values)||void 0===r?void 0:r.toArray),u=Array.isArray(t.values);if(!a||!t.values||!u&&!s)return t;var l=s?t.values.toArray():u?t.values:null;if(null===l)return t;var c=a?l.map((function(t){return"string"==typeof t?t.split("|"):t}))[0].map((function(t,e,n){return Number.isNaN(Number(t))?t:Number(t)})):null;return i(i({},t),{type:(null==c?void 0:c.every((function(t){return"number"==typeof t})))?o.FieldType.number:t.type,values:c?new o.ArrayVector(c):l})}))}))}));return i({series:r},n)}}var lt=["source","target","value"];n.d(e,"plugin",(function(){return ct}));var ct=new o.PanelPlugin((function(t){var e=t.data,n=a(t,["data"]),r=Object(u.useMemo)(ut,[]),o=Object(u.useMemo)((function(){return r(e)}),[r,e]);return l.a.createElement(st,i({},i(i({},n),{data:o})))})).setPanelOptions((function(t){return t.addSelect({path:"align",name:"Align",defaultValue:"Justify",settings:{options:[{value:"Justify",label:"Justify"},{value:"Left",label:"Left"},{value:"Right",label:"Right"},{value:"Center",label:"Center"}]}}).addTextInput({path:"colorArray",name:"Color Object",defaultValue:""}).addSelect({path:"colorScheme",name:"Color",defaultValue:"Tableau10",settings:{options:[{value:"Tableau10",label:"Tableau10"},{value:"Category10",label:"Category10"},{value:"Accent",label:"Accent"},{value:"Dark2",label:"Dark2"},{value:"Paired",label:"Paired"},{value:"Pastel1",label:"Pastel1"},{value:"Pastel2",label:"Pastel2"},{value:"Set1",label:"Set1"},{value:"Set2",label:"Set2"},{value:"Set3",label:"Set3"}]}}).addSelect({path:"edgeColor",name:"Edge Color",defaultValue:"path",settings:{options:[{value:"path",label:"input-output"},{value:"input",label:"input"},{value:"output",label:"output"},{value:"none",label:"none"}]}}).addSelect({path:"displayValues",name:"Display Values",defaultValue:"none",settings:{options:[{value:"total",label:"Totals"},{value:"percentage",label:"Percentages"},{value:"both",label:"Both"},{value:"none",label:"None"}]}}).addBooleanSwitch({path:"highlightOnHover",name:"Highlight connections on node hover",defaultValue:!1})}))}])})); +define(["react","d3","@grafana/data","@grafana/ui"],(function(t,e,n,r){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=5)}([function(e,n){e.exports=t},function(t,n){t.exports=e},function(t,e){t.exports=n},function(t,e){t.exports=r},,function(t,e,n){"use strict";n.r(e);var r={};n.r(r),n.d(r,"sankey",(function(){return M})),n.d(r,"sankeyCenter",(function(){return v})),n.d(r,"sankeyLeft",(function(){return g})),n.d(r,"sankeyRight",(function(){return p})),n.d(r,"sankeyJustify",(function(){return _})),n.d(r,"sankeyLinkHorizontal",(function(){return q}));var o=n(2);var i=function(){return(i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=i.next()).done;)a.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a}var u=n(0),l=n.n(u),c=n(1);function f(t,e){let n=0;if(void 0===e)for(let e of t)(e=+e)&&(n+=e);else{let r=-1;for(let o of t)(o=+e(o,++r,t))&&(n+=o)}return n}function h(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n=e)&&(n=e);else{let r=-1;for(let o of t)null!=(o=e(o,++r,t))&&(n=o)&&(n=o)}return n}function d(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n>e||void 0===n&&e>=e)&&(n=e);else{let r=-1;for(let o of t)null!=(o=e(o,++r,t))&&(n>o||void 0===n&&o>=o)&&(n=o)}return n}function y(t){return t.target.depth}function g(t){return t.depth}function p(t,e){return e-1-t.height}function _(t,e){return t.sourceLinks.length?t.depth:e-1}function v(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?d(t.sourceLinks,y)-1:0}function k(t){return function(){return t}}function m(t,e){return x(t.source,e.source)||t.index-e.index}function b(t,e){return x(t.target,e.target)||t.index-e.index}function x(t,e){return t.y0-e.y0}function w(t){return t.value}function S(t){return t.index}function L(t){return t.nodes}function A(t){return t.links}function O(t,e){const n=t.get(e);if(!n)throw new Error("missing: "+e);return n}function j({nodes:t}){for(const e of t){let t=e.y0,n=t;for(const n of e.sourceLinks)n.y0=t+n.width/2,t+=n.width;for(const t of e.targetLinks)t.y1=n+t.width/2,n+=t.width}}function M(){let t,e,n,r=0,o=0,i=1,a=1,s=24,u=8,l=S,c=_,y=L,g=A,p=6;function v(){const t={nodes:y.apply(null,arguments),links:g.apply(null,arguments)};return M(t),T(t),V(t),P(t),E(t),j(t),t}function M({nodes:t,links:e}){for(const[e,n]of t.entries())n.index=e,n.sourceLinks=[],n.targetLinks=[];const r=new Map(t.map((e,n)=>[l(e,n,t),e]));for(const[t,n]of e.entries()){n.index=t;let{source:e,target:o}=n;"object"!=typeof e&&(e=n.source=O(r,e)),"object"!=typeof o&&(o=n.target=O(r,o)),e.sourceLinks.push(n),o.targetLinks.push(n)}if(null!=n)for(const{sourceLinks:e,targetLinks:r}of t)e.sort(n),r.sort(n)}function T({nodes:t}){for(const e of t)e.value=void 0===e.fixedValue?Math.max(f(e.sourceLinks,w),f(e.targetLinks,w)):e.fixedValue}function V({nodes:t}){const e=t.length;let n=new Set(t),r=new Set,o=0;for(;n.size;){for(const t of n){t.depth=o;for(const{target:e}of t.sourceLinks)r.add(e)}if(++o>e)throw new Error("circular link");n=r,r=new Set}}function P({nodes:t}){const e=t.length;let n=new Set(t),r=new Set,o=0;for(;n.size;){for(const t of n){t.height=o;for(const{source:e}of t.targetLinks)r.add(e)}if(++o>e)throw new Error("circular link");n=r,r=new Set}}function E(n){const l=function({nodes:t}){const n=h(t,t=>t.depth)+1,o=(i-r-s)/(n-1),a=new Array(n);for(const e of t){const t=Math.max(0,Math.min(n-1,Math.floor(c.call(null,e,n))));e.layer=t,e.x0=r+t*o,e.x1=e.x0+s,a[t]?a[t].push(e):a[t]=[e]}if(e)for(const t of a)t.sort(e);return a}(n);t=Math.min(u,(a-o)/(h(l,t=>t.length)-1)),function(e){const n=d(e,e=>(a-o-(e.length-1)*t)/f(e,w));for(const r of e){let e=o;for(const o of r){o.y0=e,o.y1=e+o.value*n,e=o.y1+t;for(const t of o.sourceLinks)t.width=t.value*n}e=(a-e+t)/(r.length+1);for(let t=0;t0))continue;let o=(e/r-t.y0)*n;t.y0+=o,t.y1+=o,F(t)}void 0===e&&i.sort(x),B(i,r)}}function N(t,n,r){for(let o=t.length-2;o>=0;--o){const i=t[o];for(const t of i){let e=0,r=0;for(const{target:n,value:o}of t.sourceLinks){let i=o*(n.layer-t.layer);e+=I(t,n)*i,r+=i}if(!(r>0))continue;let o=(e/r-t.y0)*n;t.y0+=o,t.y1+=o,F(t)}void 0===e&&i.sort(x),B(i,r)}}function B(e,n){const r=e.length>>1,i=e[r];z(e,i.y0-t,r-1,n),H(e,i.y1+t,r+1,n),z(e,a,e.length-1,n),H(e,o,0,n)}function H(e,n,r,o){for(;r1e-6&&(i.y0+=a,i.y1+=a),n=i.y1+t}}function z(e,n,r,o){for(;r>=0;--r){const i=e[r],a=(i.y1-n)*o;a>1e-6&&(i.y0-=a,i.y1-=a),n=i.y0-t}}function F({sourceLinks:t,targetLinks:e}){if(void 0===n){for(const{source:{sourceLinks:t}}of e)t.sort(b);for(const{target:{targetLinks:e}}of t)e.sort(m)}}function J(t){if(void 0===n)for(const{sourceLinks:e,targetLinks:n}of t)e.sort(b),n.sort(m)}function G(e,n){let r=e.y0-(e.sourceLinks.length-1)*t/2;for(const{target:o,width:i}of e.sourceLinks){if(o===n)break;r+=i+t}for(const{source:t,width:o}of n.targetLinks){if(t===e)break;r-=o}return r}function I(e,n){let r=n.y0-(n.targetLinks.length-1)*t/2;for(const{source:o,width:i}of n.targetLinks){if(o===e)break;r+=i+t}for(const{target:t,width:o}of e.sourceLinks){if(t===n)break;r-=o}return r}return v.update=function(t){return j(t),t},v.nodeId=function(t){return arguments.length?(l="function"==typeof t?t:k(t),v):l},v.nodeAlign=function(t){return arguments.length?(c="function"==typeof t?t:k(t),v):c},v.nodeSort=function(t){return arguments.length?(e=t,v):e},v.nodeWidth=function(t){return arguments.length?(s=+t,v):s},v.nodePadding=function(e){return arguments.length?(u=t=+e,v):u},v.nodes=function(t){return arguments.length?(y="function"==typeof t?t:k(t),v):y},v.links=function(t){return arguments.length?(g="function"==typeof t?t:k(t),v):g},v.linkSort=function(t){return arguments.length?(n=t,v):n},v.size=function(t){return arguments.length?(r=o=0,i=+t[0],a=+t[1],v):[i-r,a-o]},v.extent=function(t){return arguments.length?(r=+t[0][0],i=+t[1][0],o=+t[0][1],a=+t[1][1],v):[[r,o],[i,a]]},v.iterations=function(t){return arguments.length?(p=+t,v):p},v}var T=Math.PI,V=2*T,P=V-1e-6;function E(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function C(){return new E}E.prototype=C.prototype={constructor:E,moveTo:function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},quadraticCurveTo:function(t,e,n,r){this._+="Q"+ +t+","+ +e+","+(this._x1=+n)+","+(this._y1=+r)},bezierCurveTo:function(t,e,n,r,o,i){this._+="C"+ +t+","+ +e+","+ +n+","+ +r+","+(this._x1=+o)+","+(this._y1=+i)},arcTo:function(t,e,n,r,o){t=+t,e=+e,n=+n,r=+r,o=+o;var i=this._x1,a=this._y1,s=n-t,u=r-e,l=i-t,c=a-e,f=l*l+c*c;if(o<0)throw new Error("negative radius: "+o);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(f>1e-6)if(Math.abs(c*s-u*l)>1e-6&&o){var h=n-i,d=r-a,y=s*s+u*u,g=h*h+d*d,p=Math.sqrt(y),_=Math.sqrt(f),v=o*Math.tan((T-Math.acos((y+f-g)/(2*p*_)))/2),k=v/_,m=v/p;Math.abs(k-1)>1e-6&&(this._+="L"+(t+k*l)+","+(e+k*c)),this._+="A"+o+","+o+",0,0,"+ +(c*h>l*d)+","+(this._x1=t+m*s)+","+(this._y1=e+m*u)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,r,o,i){t=+t,e=+e,i=!!i;var a=(n=+n)*Math.cos(r),s=n*Math.sin(r),u=t+a,l=e+s,c=1^i,f=i?r-o:o-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+u+","+l:(Math.abs(this._x1-u)>1e-6||Math.abs(this._y1-l)>1e-6)&&(this._+="L"+u+","+l),n&&(f<0&&(f=f%V+V),f>P?this._+="A"+n+","+n+",0,1,"+c+","+(t-a)+","+(e-s)+"A"+n+","+n+",0,1,"+c+","+(this._x1=u)+","+(this._y1=l):f>1e-6&&(this._+="A"+n+","+n+",0,"+ +(f>=T)+","+c+","+(this._x1=t+n*Math.cos(o))+","+(this._y1=e+n*Math.sin(o))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var N=C,B=Array.prototype.slice,H=function(t){return function(){return t}};function z(t){return t[0]}function F(t){return t[1]}function J(t){return t.source}function G(t){return t.target}function I(t){var e=J,n=G,r=z,o=F,i=null;function a(){var a,s=B.call(arguments),u=e.apply(this,s),l=n.apply(this,s);if(i||(i=a=N()),t(i,+r.apply(this,(s[0]=u,s)),+o.apply(this,s),+r.apply(this,(s[0]=l,s)),+o.apply(this,s)),a)return i=null,a+""||null}return a.source=function(t){return arguments.length?(e=t,a):e},a.target=function(t){return arguments.length?(n=t,a):n},a.x=function(t){return arguments.length?(r="function"==typeof t?t:H(+t),a):r},a.y=function(t){return arguments.length?(o="function"==typeof t?t:H(+t),a):o},a.context=function(t){return arguments.length?(i=null==t?null:t,a):i},a}function D(t,e,n,r,o){t.moveTo(e,n),t.bezierCurveTo(e=(e+r)/2,n,e,o,r,o)}function R(t){return[t.source.x1,t.y0]}function W(t){return[t.target.x0,t.y1]}var q=function(){return I(D).source(R).target(W)};function U(t,e){for(var n=0;n0&&this._data.links.length>0}},{key:"_setLinkGradient",value:function(){var t=this,e=this._svgLink.append("linearGradient").attr("id",(function(t){return t.uid="link-".concat(t.index,"-").concat(Math.random())})).attr("gradientUnits","userSpaceOnUse").attr("x1",(function(t){return t.source.x1})).attr("x2",(function(t){return t.target.x0}));e.append("stop").attr("offset","0%").attr("stop-color",(function(e){return t._color(e.source)})),e.append("stop").attr("offset","100%").attr("stop-color",(function(e){return t._color(e.target)}))}},{key:"_setLinkStroke",value:function(t){switch(this._edgeColor){case X:return"#aaa";case Y:return"url(#".concat(t.uid,")");case $:return this._color(t.source);case tt:return this._color(t.target);default:return}}},{key:"_showLinks",value:function(t){var e=[];[{linkType:"sourceLinks",nodeType:"target"},{linkType:"targetLinks",nodeType:"source"}].forEach((function(n){t[n.linkType].forEach((function(t){e.push(t[n.nodeType])}))})),this._gBound.selectAll(".sankey-node").style("opacity",(function(n){return t.name===n.name||e.find((function(t){return t.name===n.name}))?"1":"0.2"})),this._gBound.selectAll(".sankey-link").style("opacity",(function(e){return!e||e.source.name!==t.name&&e.target.name!==t.name?"0.2":"1"}))}},{key:"_showAll",value:function(){this._gBound.selectAll(".sankey-node").style("opacity","1"),this._gBound.selectAll(".sankey-link").style("opacity","1")}},{key:"_formatValue",value:function(t){return c.format(".2~f")(t)}},{key:"_formatPercent",value:function(t){return c.format(".2~%")(t)}},{key:"_formatThousand",value:function(t){return c.format(".3~s")(t)}},{key:"_labelNodeValue",value:function(t){var e=this._nodes.filter((function(e){return e.depth===t.depth})),n=c.sum(e,(function(t){return t.value})),r=this._formatThousand(t.value),o=this._formatPercent(t.value/n),i="";switch(this._displayValues){case Z:i="".concat(r);break;case Q:i="".concat(o);break;case K:i="".concat(o," - ").concat(r)}return i}},{key:"_renderSVG",value:function(){var t=this;this._container.style("background-color",this._background),this._gBound=this._container.append("g").attr("transform","translate(".concat(this._marginLeft,", ").concat(this._marginTop,")")),this._svgNode=this._gBound.append("g").attr("stroke","#000").selectAll(".sankey-node").data(this._nodes,(function(t){return t.name})).join("rect").attr("class","sankey-node").attr("id",(function(t){return t.name})).attr("x",(function(t){return t.x0})).attr("y",(function(t){return t.y0})).attr("rx",2).attr("ry",2).attr("height",(function(t){return t.y1-t.y0})).attr("width",(function(t){return t.x1-t.x0})).attr("stroke",(function(e){var n=JSON.parse(t._colorArray);return Object.keys(n).includes(e.name)?n[e.name]:"rgba(148, 153, 168, 1)"})).attr("fill",(function(e){var n=JSON.parse(t._colorArray);return Object.keys(n).includes(e.name)?n[e.name]:"rgba(148, 153, 168, 1)"})).on("mouseover",(function(e){return t._highlightOnHover&&t._showLinks(e)})).on("mouseout",(function(e){return t._highlightOnHover&&t._showAll()})),this._svgLink=this._gBound.append("g").attr("fill","none").attr("stroke-opacity",.3).selectAll("g").data(this._links,(function(t){return"".concat(t.source.name,"-").concat(t.target.name)})).join("g").style("mix-blend-mode","multiply"),"path"===this._edgeColor&&this._setLinkGradient(),this._svgLink.append("path").attr("class","sankey-link").attr("d",q()).attr("stroke","rgba(182, 185, 196, 1)").attr("stroke-width",(function(t){return Math.max(1,t.width)})),this._gBound.append("g").attr("font-family","sans-serif").attr("font-size",10).selectAll("text").data(this._nodes).join("text").attr("x",(function(t){return t.x0+8})).attr("y",(function(t){return(t.y1+t.y0)/2})).attr("dy","0.35em").text((function(t){return t.name})),this._gBound.append("g").attr("font-family","sans-serif").attr("font-size",10).selectAll("text").data(this._nodes).join("text").attr("x",(function(t){return t.x0+8})).attr("font-size",14).attr("font-weight","700").attr("y",(function(t){return(t.y1+t.y0)/2+16})).attr("dy","0.35em").text((function(e){return t._labelNodeValue(e)})),this._svgNode.append("title").text((function(e){return"".concat(e.name,"\n").concat(t._formatValue(e.value))})),this._svgLink.append("title").text((function(e){return"".concat(e.source.name," → ").concat(e.target.name,"\n").concat(t._formatValue(e.value))}))}},{key:"data",value:function(t){return arguments.length?(this._data=t,this):this._data}},{key:"width",value:function(t){return arguments.length?(this._width=+t,this):this._width}},{key:"height",value:function(t){return arguments.length?(this._height=+t,this):this._height}},{key:"align",value:function(t){return arguments.length?(this._sankeyAlignType=t,this):this._sankeyAlignType}},{key:"colorScheme",value:function(t){return arguments.length?(this._colorScheme=t,this):this._colorScheme}},{key:"colorArray",value:function(t){return arguments.length?(this._colorArray=t,this):this._colorArray}},{key:"edgeColor",value:function(t){return arguments.length?(this._edgeColor=t,this):this._edgeColor}},{key:"displayValues",value:function(t){return arguments.length?(this._displayValues=t,this):this._displayValues}},{key:"highlightOnHover",value:function(t){return arguments.length?(this._highlightOnHover=t,this):this._highlightOnHover}},{key:"render",value:function(){return this._validate()&&(this._init(),this._renderSVG()),this}}])&&U(e.prototype,n),o&&U(e,o),t}(),nt=n(3),rt=function(t){var e=t.message;return l.a.createElement("p",{style:ot},l.a.createElement("div",{style:it},l.a.createElement(nt.Icon,{name:"exclamation-triangle"}),l.a.createElement("div",{style:at},e)))},ot={height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},it={padding:"15px 20px",marginBottom:"4px",position:"relative",color:"rgb(255, 255, 255)",textShadow:"rgb(0 0 0 / 20%) 0px 1px 0px",borderRadius:"3px",display:"flex",flexDirection:"row",alignItems:"center",background:"linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))"},at={marginLeft:10},st=function(t){void 0===t&&(t=!0);if(!t)return{warn:function(){for(var t=[],e=0;e= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","export default function sum(values, valueof) {\n let sum = 0;\n if (valueof === undefined) {\n for (let value of values) {\n if (value = +value) {\n sum += value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if (value = +valueof(value, ++index, values)) {\n sum += value;\n }\n }\n }\n return sum;\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","import {min} from \"d3-array\";\n\nfunction targetDepth(d) {\n return d.target.depth;\n}\n\nexport function left(node) {\n return node.depth;\n}\n\nexport function right(node, n) {\n return n - 1 - node.height;\n}\n\nexport function justify(node, n) {\n return node.sourceLinks.length ? node.depth : n - 1;\n}\n\nexport function center(node) {\n return node.targetLinks.length ? node.depth\n : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1\n : 0;\n}\n","export default function constant(x) {\n return function() {\n return x;\n };\n}\n","import {max, min, sum} from \"d3-array\";\nimport {justify} from \"./align.js\";\nimport constant from \"./constant.js\";\n\nfunction ascendingSourceBreadth(a, b) {\n return ascendingBreadth(a.source, b.source) || a.index - b.index;\n}\n\nfunction ascendingTargetBreadth(a, b) {\n return ascendingBreadth(a.target, b.target) || a.index - b.index;\n}\n\nfunction ascendingBreadth(a, b) {\n return a.y0 - b.y0;\n}\n\nfunction value(d) {\n return d.value;\n}\n\nfunction defaultId(d) {\n return d.index;\n}\n\nfunction defaultNodes(graph) {\n return graph.nodes;\n}\n\nfunction defaultLinks(graph) {\n return graph.links;\n}\n\nfunction find(nodeById, id) {\n const node = nodeById.get(id);\n if (!node) throw new Error(\"missing: \" + id);\n return node;\n}\n\nfunction computeLinkBreadths({nodes}) {\n for (const node of nodes) {\n let y0 = node.y0;\n let y1 = y0;\n for (const link of node.sourceLinks) {\n link.y0 = y0 + link.width / 2;\n y0 += link.width;\n }\n for (const link of node.targetLinks) {\n link.y1 = y1 + link.width / 2;\n y1 += link.width;\n }\n }\n}\n\nexport default function Sankey() {\n let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent\n let dx = 24; // nodeWidth\n let dy = 8, py; // nodePadding\n let id = defaultId;\n let align = justify;\n let sort;\n let linkSort;\n let nodes = defaultNodes;\n let links = defaultLinks;\n let iterations = 6;\n\n function sankey() {\n const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)};\n computeNodeLinks(graph);\n computeNodeValues(graph);\n computeNodeDepths(graph);\n computeNodeHeights(graph);\n computeNodeBreadths(graph);\n computeLinkBreadths(graph);\n return graph;\n }\n\n sankey.update = function(graph) {\n computeLinkBreadths(graph);\n return graph;\n };\n\n sankey.nodeId = function(_) {\n return arguments.length ? (id = typeof _ === \"function\" ? _ : constant(_), sankey) : id;\n };\n\n sankey.nodeAlign = function(_) {\n return arguments.length ? (align = typeof _ === \"function\" ? _ : constant(_), sankey) : align;\n };\n\n sankey.nodeSort = function(_) {\n return arguments.length ? (sort = _, sankey) : sort;\n };\n\n sankey.nodeWidth = function(_) {\n return arguments.length ? (dx = +_, sankey) : dx;\n };\n\n sankey.nodePadding = function(_) {\n return arguments.length ? (dy = py = +_, sankey) : dy;\n };\n\n sankey.nodes = function(_) {\n return arguments.length ? (nodes = typeof _ === \"function\" ? _ : constant(_), sankey) : nodes;\n };\n\n sankey.links = function(_) {\n return arguments.length ? (links = typeof _ === \"function\" ? _ : constant(_), sankey) : links;\n };\n\n sankey.linkSort = function(_) {\n return arguments.length ? (linkSort = _, sankey) : linkSort;\n };\n\n sankey.size = function(_) {\n return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0];\n };\n\n sankey.extent = function(_) {\n return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]];\n };\n\n sankey.iterations = function(_) {\n return arguments.length ? (iterations = +_, sankey) : iterations;\n };\n\n function computeNodeLinks({nodes, links}) {\n for (const [i, node] of nodes.entries()) {\n node.index = i;\n node.sourceLinks = [];\n node.targetLinks = [];\n }\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d]));\n for (const [i, link] of links.entries()) {\n link.index = i;\n let {source, target} = link;\n if (typeof source !== \"object\") source = link.source = find(nodeById, source);\n if (typeof target !== \"object\") target = link.target = find(nodeById, target);\n source.sourceLinks.push(link);\n target.targetLinks.push(link);\n }\n if (linkSort != null) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(linkSort);\n targetLinks.sort(linkSort);\n }\n }\n }\n\n function computeNodeValues({nodes}) {\n for (const node of nodes) {\n node.value = node.fixedValue === undefined\n ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value))\n : node.fixedValue;\n }\n }\n\n function computeNodeDepths({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.depth = x;\n for (const {target} of node.sourceLinks) {\n next.add(target);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeHeights({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.height = x;\n for (const {source} of node.targetLinks) {\n next.add(source);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeLayers({nodes}) {\n const x = max(nodes, d => d.depth) + 1;\n const kx = (x1 - x0 - dx) / (x - 1);\n const columns = new Array(x);\n for (const node of nodes) {\n const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x))));\n node.layer = i;\n node.x0 = x0 + i * kx;\n node.x1 = node.x0 + dx;\n if (columns[i]) columns[i].push(node);\n else columns[i] = [node];\n }\n if (sort) for (const column of columns) {\n column.sort(sort);\n }\n return columns;\n }\n\n function initializeNodeBreadths(columns) {\n const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value));\n for (const nodes of columns) {\n let y = y0;\n for (const node of nodes) {\n node.y0 = y;\n node.y1 = y + node.value * ky;\n y = node.y1 + py;\n for (const link of node.sourceLinks) {\n link.width = link.value * ky;\n }\n }\n y = (y1 - y + py) / (nodes.length + 1);\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n node.y0 += y * (i + 1);\n node.y1 += y * (i + 1);\n }\n reorderLinks(nodes);\n }\n }\n\n function computeNodeBreadths(graph) {\n const columns = computeNodeLayers(graph);\n py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1));\n initializeNodeBreadths(columns);\n for (let i = 0; i < iterations; ++i) {\n const alpha = Math.pow(0.99, i);\n const beta = Math.max(1 - alpha, (i + 1) / iterations);\n relaxRightToLeft(columns, alpha, beta);\n relaxLeftToRight(columns, alpha, beta);\n }\n }\n\n // Reposition each node based on its incoming (target) links.\n function relaxLeftToRight(columns, alpha, beta) {\n for (let i = 1, n = columns.length; i < n; ++i) {\n const column = columns[i];\n for (const target of column) {\n let y = 0;\n let w = 0;\n for (const {source, value} of target.targetLinks) {\n let v = value * (target.layer - source.layer);\n y += targetTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - target.y0) * alpha;\n target.y0 += dy;\n target.y1 += dy;\n reorderNodeLinks(target);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n // Reposition each node based on its outgoing (source) links.\n function relaxRightToLeft(columns, alpha, beta) {\n for (let n = columns.length, i = n - 2; i >= 0; --i) {\n const column = columns[i];\n for (const source of column) {\n let y = 0;\n let w = 0;\n for (const {target, value} of source.sourceLinks) {\n let v = value * (target.layer - source.layer);\n y += sourceTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - source.y0) * alpha;\n source.y0 += dy;\n source.y1 += dy;\n reorderNodeLinks(source);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n function resolveCollisions(nodes, alpha) {\n const i = nodes.length >> 1;\n const subject = nodes[i];\n resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);\n resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);\n resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha);\n resolveCollisionsTopToBottom(nodes, y0, 0, alpha);\n }\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(nodes, y, i, alpha) {\n for (; i < nodes.length; ++i) {\n const node = nodes[i];\n const dy = (y - node.y0) * alpha;\n if (dy > 1e-6) node.y0 += dy, node.y1 += dy;\n y = node.y1 + py;\n }\n }\n\n // Push any overlapping nodes up.\n function resolveCollisionsBottomToTop(nodes, y, i, alpha) {\n for (; i >= 0; --i) {\n const node = nodes[i];\n const dy = (node.y1 - y) * alpha;\n if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy;\n y = node.y0 - py;\n }\n }\n\n function reorderNodeLinks({sourceLinks, targetLinks}) {\n if (linkSort === undefined) {\n for (const {source: {sourceLinks}} of targetLinks) {\n sourceLinks.sort(ascendingTargetBreadth);\n }\n for (const {target: {targetLinks}} of sourceLinks) {\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n function reorderLinks(nodes) {\n if (linkSort === undefined) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(ascendingTargetBreadth);\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n // Returns the target.y0 that would produce an ideal link from source to target.\n function targetTop(source, target) {\n let y = source.y0 - (source.sourceLinks.length - 1) * py / 2;\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y += width + py;\n }\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y -= width;\n }\n return y;\n }\n\n // Returns the source.y0 that would produce an ideal link from source to target.\n function sourceTop(source, target) {\n let y = target.y0 - (target.targetLinks.length - 1) * py / 2;\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y += width + py;\n }\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y -= width;\n }\n return y;\n }\n\n return sankey;\n}\n","var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n","export var slice = Array.prototype.slice;\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import {path} from \"d3-path\";\nimport {slice} from \"../array.js\";\nimport constant from \"../constant.js\";\nimport {x as pointX, y as pointY} from \"../point.js\";\nimport pointRadial from \"../pointRadial.js\";\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link(curve) {\n var source = linkSource,\n target = linkTarget,\n x = pointX,\n y = pointY,\n context = null;\n\n function link() {\n var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), link) : x;\n };\n\n link.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), link) : y;\n };\n\n link.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nexport function linkHorizontal() {\n return link(curveHorizontal);\n}\n\nexport function linkVertical() {\n return link(curveVertical);\n}\n\nexport function linkRadial() {\n var l = link(curveRadial);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n","import {linkHorizontal} from \"d3-shape\";\n\nfunction horizontalSource(d) {\n return [d.source.x1, d.y0];\n}\n\nfunction horizontalTarget(d) {\n return [d.target.x0, d.y1];\n}\n\nexport default function() {\n return linkHorizontal()\n .source(horizontalSource)\n .target(horizontalTarget);\n}\n","import * as d3 from 'd3';\nimport * as d3Sankey from 'd3-sankey';\n\nconst DISPLAY_VALUES = { total: 'total', percentage: 'percentage', both: 'both', none: 'none' };\nconst EDGE_COLORS = { none: 'none', path: 'path', input: 'input', output: 'output'};\n\nexport class Sankey {\n constructor(svg, container) {\n this._svg = svg;\n this._container = container || svg;\n this._gBound = null;\n\n this._data = null;\n this._nodes = null;\n this._links = null;\n\n this._width = 0;\n this._height = 0;\n this._boundedWidth = 0;\n this._boundedHeight = 0;\n\n this._marginTop = 20;\n this._marginRight = 20;\n this._marginBottom = 20;\n this._marginLeft = 20;\n\n this._background = 'rgba(0, 0, 0, 0)';\n this._edgeColor = 'path';\n this._colorScheme = 'Tableau10';\n this._colorScale = null;\n this._colorArray = '';\n\n this._sankeyAlignType = 'Justify';\n this._sankeyAlign = null;\n this._sankeyGenerator = null;\n this._sankeyNodeWith = 85;\n this._sankeyNodePadding = 20;\n\n this._svgNode = null;\n this._svgLink = null;\n\n this._displayValues = 'none';\n this._highlightOnHover = false;\n\n }\n \n _init() {\n this._setBoundDimensions();\n this._setColorScale();\n this._configureSankey();\n this._calculateSankey();\n }\n\n // ---------------------------- DIMENSIONS ----------------------------\n\n _setBoundDimensions() {\n this._boundedWidth = this._width - this._marginLeft - this._marginRight;\n this._boundedHeight = this._height - this._marginTop - this._marginBottom;\n }\n\n // ------------------------------ COLOR -------------------------------\n\n _setColorScale() {\n this._colorScale = d3.scaleOrdinal(d3[`scheme${this._colorScheme}`]);\n }\n\n _color(node) {\n return this._colorScale(node.name);\n }\n\n // ------------------------------ SANKEY -------------------------------\n\n _configureSankey() {\n this._sankeyAlign = d3Sankey[`sankey${this._sankeyAlignType}`];\n\n this._sankeyGenerator = d3Sankey\n .sankey()\n .nodeId(d => d.name)\n .nodeAlign(this._sankeyAlign)\n .nodeWidth(this._sankeyNodeWith)\n .nodePadding(this._sankeyNodePadding)\n .extent([\n [0, 0],\n [this._boundedWidth, this._boundedHeight],\n ]);\n }\n\n _calculateSankey() {\n const sankeyData = this._sankeyGenerator({\n nodes: this._data.nodes.map(d => Object.assign({}, d)),\n links: this._data.links.map(d => Object.assign({}, d))\n });\n\n this._nodes = sankeyData.nodes;\n this._links = sankeyData.links;\n }\n\n // ---------------------------- VALIDATIONS -----------------------------\n\n _validate() {\n return this._data &&\n this._data.nodes &&\n this._data.links &&\n this._data.nodes.length > 0 &&\n this._data.links.length > 0\n }\n\n // ------------------------------ HELPERS -------------------------------\n\n _setLinkGradient() {\n const gradient = this._svgLink\n .append('linearGradient')\n .attr('id', d => (d.uid = `link-${d.index}-${Math.random()}`))\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', d => d.source.x1)\n .attr('x2', d => d.target.x0);\n\n gradient\n .append('stop')\n .attr('offset', '0%')\n .attr('stop-color', d => this._color(d.source));\n\n gradient\n .append('stop')\n .attr('offset', '100%')\n .attr('stop-color', d => this._color(d.target));\n }\n\n _setLinkStroke(d) {\n switch (this._edgeColor) {\n case EDGE_COLORS.none:\n return '#aaa';\n case EDGE_COLORS.path:\n return `url(#${d.uid})`;\n case EDGE_COLORS.input:\n return this._color(d.source)\n case EDGE_COLORS.output:\n return this._color(d.target)\n default:\n return\n }\n }\n\n // NODE HOVER\n _showLinks(currentNode) {\n const linkedNodes = [];\n\n let traverse = [\n {\n linkType: 'sourceLinks',\n nodeType: 'target',\n },\n {\n linkType: 'targetLinks',\n nodeType: 'source',\n },\n ];\n\n traverse.forEach(step => {\n currentNode[step.linkType].forEach(l => {\n linkedNodes.push(l[step.nodeType]);\n });\n });\n\n // highlight linked nodes\n this._gBound\n .selectAll('.sankey-node')\n .style('opacity', node =>\n currentNode.name === node.name ||\n linkedNodes.find(linkedNode => linkedNode.name === node.name) ? \n '1' : '0.2'\n );\n\n // highlight links\n this._gBound\n .selectAll('.sankey-link')\n .style('opacity', link =>\n link && (\n link.source.name === currentNode.name || \n link.target.name === currentNode.name\n ) ? \n '1' : '0.2'\n );\n };\n\n _showAll() {\n this._gBound.selectAll('.sankey-node').style('opacity', '1');\n this._gBound.selectAll('.sankey-link').style('opacity', '1');\n };\n\n // NODE LABELING\n _formatValue(value) { return d3.format('.2~f')(value); }\n _formatPercent(percent) { return d3.format('.2~%')(percent); }\n _formatThousand(value) { return d3.format('.3~s')(value); }\n\n _labelNode(currentNode) {\n const nodesAtDepth = this._nodes.filter(node => node.depth === currentNode.depth);\n const totalAtDepth = d3.sum(nodesAtDepth, node => node.value);\n const nodeValue = this._formatThousand(currentNode.value);\n const nodePercent = this._formatPercent(currentNode.value / totalAtDepth);\n\n let label = currentNode.name;\n switch (this._displayValues) {\n case DISPLAY_VALUES.total:\n label = `${label}\n ${nodeValue}`;\n break;\n case DISPLAY_VALUES.percentage:\n label = `${label}\n ${nodePercent}`;\n break;\n case DISPLAY_VALUES.both:\n label = `${label}\n ${nodePercent} - ${nodeValue}`;\n break;\n default:\n break;\n }\n return label;\n };\n\n // ------------------------------ DRAWING -------------------------------\n\n _renderSVG() {\n // BACKGROUND\n this._container.style('background-color', this._background)\n\n // BOUNDS\n this._gBound = this._container.append('g')\n .attr('transform', `translate(${this._marginLeft}, ${this._marginTop})`);\n\n // NODES\n this._svgNode = this._gBound\n .append('g')\n .attr('stroke', '#000')\n .selectAll('.sankey-node')\n .data(this._nodes, node => node.name)\n .join('rect')\n .attr('class', 'sankey-node')\n .attr('id', d => d.name)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('height', d => d.y1 - d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('stroke', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .attr('fill', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .on('mouseover', d => this._highlightOnHover && this._showLinks(d))\n .on('mouseout', _ => this._highlightOnHover && this._showAll());\n\n // LINKS\n this._svgLink = this._gBound\n .append('g')\n .attr('fill', 'none')\n .attr('stroke-opacity', 0.3)\n .selectAll('g')\n .data(this._links, link => `${link.source.name}-${link.target.name}`)\n .join('g')\n .style('mix-blend-mode', 'multiply');\n\n if (this._edgeColor === 'path') this._setLinkGradient()\n\n this._svgLink\n .append('path')\n .attr('class', 'sankey-link')\n .attr('d', d3Sankey.sankeyLinkHorizontal())\n .attr('stroke', \"rgba(182, 185, 196, 1)\")\n .attr('stroke-width', d => Math.max(1, d.width)); \n\n // LABELS\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('y', d => (d.y1 + d.y0) / 2)\n .attr('dy', '0.35em')\n //.attr('text-anchor', d => (d.x0 < this._width / 2 ? 'start' : 'end'))\n .text(d => this._labelNode(d));\n\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('font-size', 14)\n .attr('font-weight', '700')\n .attr('y', d => ((d.y1 + d.y0) / 2) + 16)\n .attr('dy', '0.35em')\n //.attr('text-anchor', d => (d.x0 < this._width / 2 ? 'start' : 'end'))\n .text(d => this._formatValue(d.value));\n\n this._svgNode\n .append('title')\n .text(d => `${d.name}\\n${this._formatValue(d.value)}`);\n\n this._svgLink\n .append('title')\n .text(d => `${d.source.name} → ${d.target.name}\\n${this._formatValue(d.value)}`);\n }\n\n\n // ----------------------------------------------------------------------- \n // ------------------------------ API ------------------------------\n // ----------------------------------------------------------------------- \n\n data(_) {\n return arguments.length ? (this._data = _, this) : this._data;\n };\n\n width(_) {\n return arguments.length ? (this._width = +_, this) : this._width;\n };\n\n height(_) {\n return arguments.length ? (this._height = +_, this) : this._height;\n };\n\n align(_) {\n return arguments.length ? (this._sankeyAlignType = _, this) : this._sankeyAlignType;\n }\n\n colorScheme(_) {\n return arguments.length ? (this._colorScheme = _, this) : this._colorScheme;\n }\n\n colorArray(_) {\n return arguments.length ? (this._colorArray = _, this) : this._colorArray;\n }\n\n edgeColor(_) {\n return arguments.length ? (this._edgeColor = _, this) : this._edgeColor;\n }\n\n displayValues(_) {\n return arguments.length ? (this._displayValues = _, this) : this._displayValues;\n }\n\n highlightOnHover(_) {\n return arguments.length ? (this._highlightOnHover = _, this) : this._highlightOnHover;\n }\n\n render() {\n if (!this._validate()) {\n // no graph data\n }\n else {\n this._init();\n this._renderSVG()\n }\n return this;\n }\n}\n","// @ts-nocheck\nimport React from 'react';\nimport { Icon } from '@grafana/ui';\n\nexport const ErrorMessage = ({ message }) => ( \n

\n

\n \n
{message}
\n
\n

\n)\n\nconst panelStyles = {\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n}\n\nconst containerStyles = {\n padding: '15px 20px',\n marginBottom: '4px',\n position: 'relative',\n color: 'rgb(255, 255, 255)',\n textShadow: 'rgb(0 0 0 / 20%) 0px 1px 0px',\n borderRadius: '3px',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n background: 'linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))'\n}\n\nconst messageStyles = {\n marginLeft: 10\n}\n","// @ts-nocheck\nimport React, { useState, useEffect } from 'react';\nimport * as d3 from 'd3';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyOptions } from 'types';\nimport { Sankey } from 'Sankey'\nimport { ErrorMessage } from 'Error'\n\ninterface Props extends PanelProps {}\n\nexport const SankeyPanel: React.FC = ({ options, data, width, height }) => {\n // ------------------------ CHART CONSTANTS -----------------------\n const CHART_REQUIRED_FIELDS = { source: 'source', target: 'target', value: 'value' };\n\n // ------------------------ ERROR MESSAGES ------------------------\n const requiredFieldsMsg = `Required fields not present: ${Object.keys(CHART_REQUIRED_FIELDS).join(', ')}`;\n const fieldTypeMsg = `Fields should have the following types: source (string), target (string), value (numeric)`;\n\n // ------------------------- REACT HOOKS --------------------------\n const [ error, setError ] = useState({ isError: false, message: '' })\n const [ graph, setGraph ] = useState({ nodes: [], links: [] })\n\n useEffect(() => {\n data.error\n ?\n setError({isError: true, message: data.error.message})\n :\n setGraph(buildGraph())\n }, [data])\n\n // ------------------------- DATA ACQUISITION -------------------------\n const validate = (sources, targets, values) => {\n let isValid = true;\n\n // REQUIRED FIELDS\n if (!(sources && targets && values)) {\n setError({ isError: true, message: requiredFieldsMsg })\n return isValid = false;\n }\n\n // FIELD TYPES\n const sourcesString = sources.every(d => typeof d === 'string')\n const targetsString = targets.every(d => typeof d === 'string')\n const valuesNumeric = values.every(d => typeof d === 'number')\n\n if (!(sourcesString && targetsString && valuesNumeric)) {\n setError({ isError: true, message: fieldTypeMsg })\n return isValid = false;\n }\n\n setError({});\n\n return isValid;\n }\n\n const buildGraph = () => {\n const frame = data.series[0];\n\n const sourceAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.source);\n const targetAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.target);\n const valueAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.value);\n\n const sources = sourceAccesor?.values.toArray();\n const targets = targetAccesor?.values.toArray();\n const values = valueAccesor?.values.toArray();\n\n const isValid = validate(sources, targets, values);\n if (!isValid) {return}\n \n const zip = d3.zip(sources, targets, values);\n \n const nodes = Array.from(new Set(sources.concat(targets))).map(node => ({ name: node }));\n const links = zip.map(d => ({ source: d[0], target: d[1], value: +d[2].toFixed(2) }));\n const graph = { nodes, links };\n\n return graph\n }\n\n // ------------------------------- CHART ------------------------------\n const chart = svg => {\n const sankey = new Sankey(svg)\n .width(width)\n .height(height)\n .align(options.align)\n .edgeColor(options.edgeColor)\n .colorScheme(options.colorScheme)\n .displayValues(options.displayValues)\n .highlightOnHover(options.highlightOnHover)\n .data(graph)\n\n try {\n sankey.render();\n } catch (renderError) {\n setError({isError: true, message: renderError.message})\n }\n };\n\n return (error.isError ?\n \n :\n {\n d3.select(node)\n .selectAll('*')\n .remove();\n d3.select(node).call(chart);\n }}\n />\n );\n};\n","// NOTE: implementation of toDataFrame: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/dataframe/processDataFrame.ts\nimport { toDataFrame, FieldType, ArrayVector, Field } from '@grafana/data';\n\nimport { SankeyOptionsFn } from 'types-fn';\n\nexport function transformFnData(): Required['transformFn'] {\n return ({ series, ...other }) => {\n const transformedSeries = series.map((data) => {\n return toDataFrame({ ...data, fields: data.fields.map(mapField()) });\n });\n\n return {\n series: transformedSeries,\n ...other,\n };\n };\n}\n\nconst SANKEY_FIELD_NAMES = ['source', 'target', 'value'];\n\n// @ts-ignore\nfunction mapField

() {\n return (field: Field

, _: number, __: Array>) => {\n const isSankeyField = SANKEY_FIELD_NAMES.includes(field.name);\n\n const isArrayVector = field.values instanceof ArrayVector || typeof field.values?.toArray === 'function';\n const isArray = Array.isArray(field.values);\n\n if (!isSankeyField || !field.values || (!isArray && !isArrayVector)) {\n return field;\n }\n\n const values = isArrayVector ? field.values.toArray() : isArray ? field.values : null;\n\n if (values === null) {\n return field;\n }\n\n const parsedValues = isSankeyField ? ((values as P[]).map(splitValue())[0] as unknown[]).map(mapToNumber()) : null;\n\n return {\n ...field,\n type: parsedValues?.every(isNumber()) ? FieldType.number : field.type,\n values: parsedValues ? new ArrayVector(parsedValues) : values,\n };\n };\n}\n\n// @ts-ignore\nfunction mapToNumber() {\n return (value: V, _: number, __: V[]) => (Number.isNaN(Number(value)) ? value : Number(value));\n}\n\n// @ts-ignore\nfunction splitValue() {\n return (value: V) => (typeof value === 'string' ? value.split('|') : value);\n}\n\n// @ts-ignore\nfunction isNumber() {\n return (value: V) => typeof value === 'number';\n}\n","import { PanelPlugin } from '@grafana/data';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { SankeyPanelFn as SankeyPanel } from './SankeyPanelFn';\n\nexport const plugin = new PanelPlugin(SankeyPanel).setPanelOptions((builder) => {\n return builder\n .addSelect({\n path: 'align',\n name: 'Align',\n defaultValue: 'Justify',\n settings: {\n options: [\n {\n value: 'Justify',\n label: 'Justify',\n },\n {\n value: 'Left',\n label: 'Left',\n },\n {\n value: 'Right',\n label: 'Right',\n },\n {\n value: 'Center',\n label: 'Center',\n },\n ],\n },\n })\n .addTextInput({\n path: 'colorArray',\n name: 'Color Object',\n defaultValue: '',\n })\n .addSelect({\n path: 'colorScheme',\n name: 'Color',\n defaultValue: 'Tableau10',\n settings: {\n options: [\n {\n value: 'Tableau10',\n label: 'Tableau10',\n },\n {\n value: 'Category10',\n label: 'Category10',\n },\n {\n value: 'Accent',\n label: 'Accent',\n },\n {\n value: 'Dark2',\n label: 'Dark2',\n },\n {\n value: 'Paired',\n label: 'Paired',\n },\n {\n value: 'Pastel1',\n label: 'Pastel1',\n },\n {\n value: 'Pastel2',\n label: 'Pastel2',\n },\n {\n value: 'Set1',\n label: 'Set1',\n },\n {\n value: 'Set2',\n label: 'Set2',\n },\n {\n value: 'Set3',\n label: 'Set3',\n },\n ],\n },\n })\n .addSelect({\n path: 'edgeColor',\n name: 'Edge Color',\n defaultValue: 'path',\n settings: {\n options: [\n {\n value: 'path',\n label: 'input-output',\n },\n {\n value: 'input',\n label: 'input',\n },\n {\n value: 'output',\n label: 'output',\n },\n {\n value: 'none',\n label: 'none',\n },\n ],\n },\n })\n .addSelect({\n path: 'displayValues',\n name: 'Display Values',\n defaultValue: 'none',\n settings: {\n options: [\n {\n value: 'total',\n label: 'Totals',\n },\n {\n value: 'percentage',\n label: 'Percentages',\n },\n {\n value: 'both',\n label: 'Both',\n },\n {\n value: 'none',\n label: 'None',\n },\n ],\n },\n })\n .addBooleanSwitch({\n path: 'highlightOnHover',\n name: 'Highlight connections on node hover',\n defaultValue: false,\n });\n});\n","import React, { useMemo, FC } from 'react';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyPanel } from 'SankeyPanel';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { transformFnData } from 'transform-fn-data';\n\nexport interface SankeyPanelFnProps extends PanelProps {}\n\nexport const SankeyPanelFn: FC = ({ data, ...props }) => {\n const transformFn = useMemo(transformFnData, []);\n\n const transformedData = useMemo(() => transformFn(data), [transformFn, data]);\n\n return ;\n};\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///external \"react\"","webpack:///external \"d3\"","webpack:///external \"@grafana/data\"","webpack:///external \"@grafana/ui\"","webpack:///../node_modules/tslib/tslib.es6.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/sum.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/max.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/min.js","webpack:///../node_modules/d3-sankey/src/align.js","webpack:///../node_modules/d3-sankey/src/constant.js","webpack:///../node_modules/d3-sankey/src/sankey.js","webpack:///../node_modules/d3-path/src/path.js","webpack:///../node_modules/d3-shape/src/array.js","webpack:///../node_modules/d3-shape/src/constant.js","webpack:///../node_modules/d3-shape/src/point.js","webpack:///../node_modules/d3-shape/src/link/index.js","webpack:///../node_modules/d3-sankey/src/sankeyLinkHorizontal.js","webpack:///./Sankey.js","webpack:///./Error.tsx","webpack:///./fn-logger.ts","webpack:///./SankeyPanel.tsx","webpack:///./transform-fn-data.ts","webpack:///./module.ts","webpack:///./SankeyPanelFn.tsx"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","__WEBPACK_EXTERNAL_MODULE__0__","__WEBPACK_EXTERNAL_MODULE__1__","__WEBPACK_EXTERNAL_MODULE__2__","__WEBPACK_EXTERNAL_MODULE__3__","__assign","assign","arguments","length","apply","this","__rest","e","indexOf","getOwnPropertySymbols","propertyIsEnumerable","__read","iterator","ar","next","done","push","error","sum","values","valueof","undefined","index","max","min","targetDepth","target","depth","left","node","right","height","justify","sourceLinks","center","targetLinks","constant","x","ascendingSourceBreadth","a","b","ascendingBreadth","source","ascendingTargetBreadth","y0","defaultId","defaultNodes","graph","nodes","defaultLinks","links","find","nodeById","id","Error","computeLinkBreadths","y1","link","width","py","sort","linkSort","x0","x1","dx","dy","align","iterations","sankey","computeNodeLinks","computeNodeValues","computeNodeDepths","computeNodeHeights","computeNodeBreadths","entries","Map","map","fixedValue","Math","current","Set","size","add","columns","kx","Array","floor","layer","column","computeNodeLayers","ky","y","reorderLinks","initializeNodeBreadths","alpha","pow","beta","relaxRightToLeft","relaxLeftToRight","w","v","targetTop","reorderNodeLinks","resolveCollisions","sourceTop","subject","resolveCollisionsBottomToTop","resolveCollisionsTopToBottom","update","nodeId","_","nodeAlign","nodeSort","nodeWidth","nodePadding","extent","pi","PI","tau","tauEpsilon","Path","_x0","_y0","_x1","_y1","path","constructor","moveTo","closePath","lineTo","quadraticCurveTo","bezierCurveTo","x2","y2","arcTo","x21","y21","x01","y01","l01_2","abs","x20","y20","l21_2","l20_2","l21","sqrt","l01","tan","acos","t01","t21","arc","a0","a1","ccw","cos","sin","cw","da","rect","h","toString","slice","linkSource","linkTarget","curve","context","buffer","argv","curveHorizontal","horizontalSource","horizontalTarget","DISPLAY_VALUES","EDGE_COLORS","Sankey","svg","container","_svg","_container","_gBound","_data","_nodes","_links","_width","_height","_boundedWidth","_boundedHeight","_marginTop","_marginRight","_marginBottom","_marginLeft","_background","_edgeColor","_colorScheme","_colorScale","_colorArray","_sankeyAlignType","_sankeyAlign","_sankeyGenerator","_sankeyNodeWith","_sankeyNodePadding","_svgNode","_svgLink","_displayValues","_highlightOnHover","_setBoundDimensions","_setColorScale","_configureSankey","_calculateSankey","d3","d3Sankey","sankeyData","filter","gradient","append","attr","uid","random","_color","currentNode","linkedNodes","linkType","nodeType","forEach","step","selectAll","style","linkedNode","percent","nodesAtDepth","totalAtDepth","nodeValue","_formatThousand","nodePercent","_formatPercent","label","data","join","colorArray","JSON","parse","keys","includes","on","_showLinks","_showAll","_setLinkGradient","text","_labelNodeValue","_formatValue","_validate","_init","_renderSVG","message","panelStyles","containerStyles","messageStyles","display","justifyContent","alignItems","padding","marginBottom","position","color","textShadow","borderRadius","flexDirection","background","marginLeft","logger","shouldLog","warn","log","console","fnLogger","options","CHART_REQUIRED_FIELDS","requiredFieldsMsg","isError","setError","setGraph","buildGraph","frame","series","sourceAccesor","fields","field","targetAccesor","valueAccesor","sources","toArray","targets","isValid","sourcesString","every","targetsString","valuesNumeric","validate","zip","from","concat","toFixed","chart","edgeColor","colorScheme","displayValues","highlightOnHover","render","renderError","viewBox","ref","remove","transformFnData","other","transformedSeries","__","isSankeyField","SANKEY_FIELD_NAMES","isArrayVector","isArray","parsedValues","split","Number","isNaN","type","number","stringify","err","String","props","transformFn","transformedData","setPanelOptions","builder","addSelect","defaultValue","settings","addTextInput","addBooleanSwitch"],"mappings":"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MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,QACP+P,MAAO,SAET,CACE/P,MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,UACP+P,MAAO,WAET,CACE/P,MAAO,UACP+P,MAAO,WAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,YAKdmG,UAAU,CACTlN,KAAM,YACN1J,KAAM,aACN6W,aAAc,OACdC,SAAU,CACR7D,QAAS,CACP,CACEvS,MAAO,OACP+P,MAAO,gBAET,CACE/P,MAAO,QACP+P,MAAO,SAET,CACE/P,MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,OACP+P,MAAO,YAKdmG,UAAU,CACTlN,KAAM,gBACN1J,KAAM,iBACN6W,aAAc,OACdC,SAAU,CACR7D,QAAS,CACP,CACEvS,MAAO,QACP+P,MAAO,UAET,CACE/P,MAAO,aACP+P,MAAO,eAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,YAKduG,iBAAiB,CAChBtN,KAAM,mBACN1J,KAAM,sCACN6W,cAAc","file":"module.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__0__;","module.exports = __WEBPACK_EXTERNAL_MODULE__1__;","module.exports = __WEBPACK_EXTERNAL_MODULE__2__;","module.exports = __WEBPACK_EXTERNAL_MODULE__3__;","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","export default function sum(values, valueof) {\n let sum = 0;\n if (valueof === undefined) {\n for (let value of values) {\n if (value = +value) {\n sum += value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if (value = +valueof(value, ++index, values)) {\n sum += value;\n }\n }\n }\n return sum;\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","import {min} from \"d3-array\";\n\nfunction targetDepth(d) {\n return d.target.depth;\n}\n\nexport function left(node) {\n return node.depth;\n}\n\nexport function right(node, n) {\n return n - 1 - node.height;\n}\n\nexport function justify(node, n) {\n return node.sourceLinks.length ? node.depth : n - 1;\n}\n\nexport function center(node) {\n return node.targetLinks.length ? node.depth\n : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1\n : 0;\n}\n","export default function constant(x) {\n return function() {\n return x;\n };\n}\n","import {max, min, sum} from \"d3-array\";\nimport {justify} from \"./align.js\";\nimport constant from \"./constant.js\";\n\nfunction ascendingSourceBreadth(a, b) {\n return ascendingBreadth(a.source, b.source) || a.index - b.index;\n}\n\nfunction ascendingTargetBreadth(a, b) {\n return ascendingBreadth(a.target, b.target) || a.index - b.index;\n}\n\nfunction ascendingBreadth(a, b) {\n return a.y0 - b.y0;\n}\n\nfunction value(d) {\n return d.value;\n}\n\nfunction defaultId(d) {\n return d.index;\n}\n\nfunction defaultNodes(graph) {\n return graph.nodes;\n}\n\nfunction defaultLinks(graph) {\n return graph.links;\n}\n\nfunction find(nodeById, id) {\n const node = nodeById.get(id);\n if (!node) throw new Error(\"missing: \" + id);\n return node;\n}\n\nfunction computeLinkBreadths({nodes}) {\n for (const node of nodes) {\n let y0 = node.y0;\n let y1 = y0;\n for (const link of node.sourceLinks) {\n link.y0 = y0 + link.width / 2;\n y0 += link.width;\n }\n for (const link of node.targetLinks) {\n link.y1 = y1 + link.width / 2;\n y1 += link.width;\n }\n }\n}\n\nexport default function Sankey() {\n let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent\n let dx = 24; // nodeWidth\n let dy = 8, py; // nodePadding\n let id = defaultId;\n let align = justify;\n let sort;\n let linkSort;\n let nodes = defaultNodes;\n let links = defaultLinks;\n let iterations = 6;\n\n function sankey() {\n const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)};\n computeNodeLinks(graph);\n computeNodeValues(graph);\n computeNodeDepths(graph);\n computeNodeHeights(graph);\n computeNodeBreadths(graph);\n computeLinkBreadths(graph);\n return graph;\n }\n\n sankey.update = function(graph) {\n computeLinkBreadths(graph);\n return graph;\n };\n\n sankey.nodeId = function(_) {\n return arguments.length ? (id = typeof _ === \"function\" ? _ : constant(_), sankey) : id;\n };\n\n sankey.nodeAlign = function(_) {\n return arguments.length ? (align = typeof _ === \"function\" ? _ : constant(_), sankey) : align;\n };\n\n sankey.nodeSort = function(_) {\n return arguments.length ? (sort = _, sankey) : sort;\n };\n\n sankey.nodeWidth = function(_) {\n return arguments.length ? (dx = +_, sankey) : dx;\n };\n\n sankey.nodePadding = function(_) {\n return arguments.length ? (dy = py = +_, sankey) : dy;\n };\n\n sankey.nodes = function(_) {\n return arguments.length ? (nodes = typeof _ === \"function\" ? _ : constant(_), sankey) : nodes;\n };\n\n sankey.links = function(_) {\n return arguments.length ? (links = typeof _ === \"function\" ? _ : constant(_), sankey) : links;\n };\n\n sankey.linkSort = function(_) {\n return arguments.length ? (linkSort = _, sankey) : linkSort;\n };\n\n sankey.size = function(_) {\n return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0];\n };\n\n sankey.extent = function(_) {\n return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]];\n };\n\n sankey.iterations = function(_) {\n return arguments.length ? (iterations = +_, sankey) : iterations;\n };\n\n function computeNodeLinks({nodes, links}) {\n for (const [i, node] of nodes.entries()) {\n node.index = i;\n node.sourceLinks = [];\n node.targetLinks = [];\n }\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d]));\n for (const [i, link] of links.entries()) {\n link.index = i;\n let {source, target} = link;\n if (typeof source !== \"object\") source = link.source = find(nodeById, source);\n if (typeof target !== \"object\") target = link.target = find(nodeById, target);\n source.sourceLinks.push(link);\n target.targetLinks.push(link);\n }\n if (linkSort != null) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(linkSort);\n targetLinks.sort(linkSort);\n }\n }\n }\n\n function computeNodeValues({nodes}) {\n for (const node of nodes) {\n node.value = node.fixedValue === undefined\n ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value))\n : node.fixedValue;\n }\n }\n\n function computeNodeDepths({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.depth = x;\n for (const {target} of node.sourceLinks) {\n next.add(target);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeHeights({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.height = x;\n for (const {source} of node.targetLinks) {\n next.add(source);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeLayers({nodes}) {\n const x = max(nodes, d => d.depth) + 1;\n const kx = (x1 - x0 - dx) / (x - 1);\n const columns = new Array(x);\n for (const node of nodes) {\n const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x))));\n node.layer = i;\n node.x0 = x0 + i * kx;\n node.x1 = node.x0 + dx;\n if (columns[i]) columns[i].push(node);\n else columns[i] = [node];\n }\n if (sort) for (const column of columns) {\n column.sort(sort);\n }\n return columns;\n }\n\n function initializeNodeBreadths(columns) {\n const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value));\n for (const nodes of columns) {\n let y = y0;\n for (const node of nodes) {\n node.y0 = y;\n node.y1 = y + node.value * ky;\n y = node.y1 + py;\n for (const link of node.sourceLinks) {\n link.width = link.value * ky;\n }\n }\n y = (y1 - y + py) / (nodes.length + 1);\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n node.y0 += y * (i + 1);\n node.y1 += y * (i + 1);\n }\n reorderLinks(nodes);\n }\n }\n\n function computeNodeBreadths(graph) {\n const columns = computeNodeLayers(graph);\n py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1));\n initializeNodeBreadths(columns);\n for (let i = 0; i < iterations; ++i) {\n const alpha = Math.pow(0.99, i);\n const beta = Math.max(1 - alpha, (i + 1) / iterations);\n relaxRightToLeft(columns, alpha, beta);\n relaxLeftToRight(columns, alpha, beta);\n }\n }\n\n // Reposition each node based on its incoming (target) links.\n function relaxLeftToRight(columns, alpha, beta) {\n for (let i = 1, n = columns.length; i < n; ++i) {\n const column = columns[i];\n for (const target of column) {\n let y = 0;\n let w = 0;\n for (const {source, value} of target.targetLinks) {\n let v = value * (target.layer - source.layer);\n y += targetTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - target.y0) * alpha;\n target.y0 += dy;\n target.y1 += dy;\n reorderNodeLinks(target);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n // Reposition each node based on its outgoing (source) links.\n function relaxRightToLeft(columns, alpha, beta) {\n for (let n = columns.length, i = n - 2; i >= 0; --i) {\n const column = columns[i];\n for (const source of column) {\n let y = 0;\n let w = 0;\n for (const {target, value} of source.sourceLinks) {\n let v = value * (target.layer - source.layer);\n y += sourceTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - source.y0) * alpha;\n source.y0 += dy;\n source.y1 += dy;\n reorderNodeLinks(source);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n function resolveCollisions(nodes, alpha) {\n const i = nodes.length >> 1;\n const subject = nodes[i];\n resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);\n resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);\n resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha);\n resolveCollisionsTopToBottom(nodes, y0, 0, alpha);\n }\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(nodes, y, i, alpha) {\n for (; i < nodes.length; ++i) {\n const node = nodes[i];\n const dy = (y - node.y0) * alpha;\n if (dy > 1e-6) node.y0 += dy, node.y1 += dy;\n y = node.y1 + py;\n }\n }\n\n // Push any overlapping nodes up.\n function resolveCollisionsBottomToTop(nodes, y, i, alpha) {\n for (; i >= 0; --i) {\n const node = nodes[i];\n const dy = (node.y1 - y) * alpha;\n if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy;\n y = node.y0 - py;\n }\n }\n\n function reorderNodeLinks({sourceLinks, targetLinks}) {\n if (linkSort === undefined) {\n for (const {source: {sourceLinks}} of targetLinks) {\n sourceLinks.sort(ascendingTargetBreadth);\n }\n for (const {target: {targetLinks}} of sourceLinks) {\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n function reorderLinks(nodes) {\n if (linkSort === undefined) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(ascendingTargetBreadth);\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n // Returns the target.y0 that would produce an ideal link from source to target.\n function targetTop(source, target) {\n let y = source.y0 - (source.sourceLinks.length - 1) * py / 2;\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y += width + py;\n }\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y -= width;\n }\n return y;\n }\n\n // Returns the source.y0 that would produce an ideal link from source to target.\n function sourceTop(source, target) {\n let y = target.y0 - (target.targetLinks.length - 1) * py / 2;\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y += width + py;\n }\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y -= width;\n }\n return y;\n }\n\n return sankey;\n}\n","var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n","export var slice = Array.prototype.slice;\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import {path} from \"d3-path\";\nimport {slice} from \"../array.js\";\nimport constant from \"../constant.js\";\nimport {x as pointX, y as pointY} from \"../point.js\";\nimport pointRadial from \"../pointRadial.js\";\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link(curve) {\n var source = linkSource,\n target = linkTarget,\n x = pointX,\n y = pointY,\n context = null;\n\n function link() {\n var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), link) : x;\n };\n\n link.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), link) : y;\n };\n\n link.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nexport function linkHorizontal() {\n return link(curveHorizontal);\n}\n\nexport function linkVertical() {\n return link(curveVertical);\n}\n\nexport function linkRadial() {\n var l = link(curveRadial);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n","import {linkHorizontal} from \"d3-shape\";\n\nfunction horizontalSource(d) {\n return [d.source.x1, d.y0];\n}\n\nfunction horizontalTarget(d) {\n return [d.target.x0, d.y1];\n}\n\nexport default function() {\n return linkHorizontal()\n .source(horizontalSource)\n .target(horizontalTarget);\n}\n","import * as d3 from 'd3';\nimport * as d3Sankey from 'd3-sankey';\n\nconst DISPLAY_VALUES = { total: 'total', percentage: 'percentage', both: 'both', none: 'none' };\nconst EDGE_COLORS = { none: 'none', path: 'path', input: 'input', output: 'output'};\n\nexport class Sankey {\n constructor(svg, container) {\n this._svg = svg;\n this._container = container || svg;\n this._gBound = null;\n\n this._data = null;\n this._nodes = null;\n this._links = null;\n\n this._width = 0;\n this._height = 0;\n this._boundedWidth = 0;\n this._boundedHeight = 0;\n\n this._marginTop = 20;\n this._marginRight = 20;\n this._marginBottom = 20;\n this._marginLeft = 20;\n\n this._background = 'rgba(0, 0, 0, 0)';\n this._edgeColor = 'path';\n this._colorScheme = 'Tableau10';\n this._colorScale = null;\n this._colorArray = '';\n\n this._sankeyAlignType = 'Justify';\n this._sankeyAlign = null;\n this._sankeyGenerator = null;\n this._sankeyNodeWith = 110;\n this._sankeyNodePadding = 20;\n\n this._svgNode = null;\n this._svgLink = null;\n\n this._displayValues = 'none';\n this._highlightOnHover = false;\n\n }\n \n _init() {\n this._setBoundDimensions();\n this._setColorScale();\n this._configureSankey();\n this._calculateSankey();\n }\n\n // ---------------------------- DIMENSIONS ----------------------------\n\n _setBoundDimensions() {\n this._boundedWidth = this._width - this._marginLeft - this._marginRight;\n this._boundedHeight = this._height - this._marginTop - this._marginBottom;\n }\n\n // ------------------------------ COLOR -------------------------------\n\n _setColorScale() {\n this._colorScale = d3.scaleOrdinal(d3[`scheme${this._colorScheme}`]);\n }\n\n _color(node) {\n return this._colorScale(node.name);\n }\n\n // ------------------------------ SANKEY -------------------------------\n\n _configureSankey() {\n this._sankeyAlign = d3Sankey[`sankey${this._sankeyAlignType}`];\n\n this._sankeyGenerator = d3Sankey\n .sankey()\n .nodeId(d => d.name)\n .nodeAlign(this._sankeyAlign)\n .nodeWidth(this._sankeyNodeWith)\n .nodePadding(this._sankeyNodePadding)\n .extent([\n [0, 0],\n [this._boundedWidth, this._boundedHeight],\n ]);\n }\n\n _calculateSankey() {\n const sankeyData = this._sankeyGenerator({\n nodes: this._data.nodes.map(d => Object.assign({}, d)),\n links: this._data.links.map(d => Object.assign({}, d))\n });\n\n this._nodes = sankeyData.nodes.filter(d => d.value !== 0);\n this._links = sankeyData.links.filter(d => d.value !== 0);\n }\n\n // ---------------------------- VALIDATIONS -----------------------------\n\n _validate() {\n return this._data &&\n this._data.nodes &&\n this._data.links &&\n this._data.nodes.length > 0 &&\n this._data.links.length > 0\n }\n\n // ------------------------------ HELPERS -------------------------------\n\n _setLinkGradient() {\n const gradient = this._svgLink\n .append('linearGradient')\n .attr('id', d => (d.uid = `link-${d.index}-${Math.random()}`))\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', d => d.source.x1)\n .attr('x2', d => d.target.x0);\n\n gradient\n .append('stop')\n .attr('offset', '0%')\n .attr('stop-color', d => this._color(d.source));\n\n gradient\n .append('stop')\n .attr('offset', '100%')\n .attr('stop-color', d => this._color(d.target));\n }\n\n _setLinkStroke(d) {\n switch (this._edgeColor) {\n case EDGE_COLORS.none:\n return '#aaa';\n case EDGE_COLORS.path:\n return `url(#${d.uid})`;\n case EDGE_COLORS.input:\n return this._color(d.source)\n case EDGE_COLORS.output:\n return this._color(d.target)\n default:\n return\n }\n }\n\n // NODE HOVER\n _showLinks(currentNode) {\n const linkedNodes = [];\n\n let traverse = [\n {\n linkType: 'sourceLinks',\n nodeType: 'target',\n },\n {\n linkType: 'targetLinks',\n nodeType: 'source',\n },\n ];\n\n traverse.forEach(step => {\n currentNode[step.linkType].forEach(l => {\n linkedNodes.push(l[step.nodeType]);\n });\n });\n\n // highlight linked nodes\n this._gBound\n .selectAll('.sankey-node')\n .style('opacity', node =>\n currentNode.name === node.name ||\n linkedNodes.find(linkedNode => linkedNode.name === node.name) ? \n '1' : '0.2'\n );\n\n // highlight links\n this._gBound\n .selectAll('.sankey-link')\n .style('opacity', link =>\n link && (\n link.source.name === currentNode.name || \n link.target.name === currentNode.name\n ) ? \n '1' : '0.2'\n );\n };\n\n _showAll() {\n this._gBound.selectAll('.sankey-node').style('opacity', '1');\n this._gBound.selectAll('.sankey-link').style('opacity', '1');\n };\n\n // NODE LABELING\n _formatValue(value) { return d3.format('.2~f')(value); }\n _formatPercent(percent) { return d3.format('.2~%')(percent); }\n _formatThousand(value) { return d3.format('.3~s')(value); }\n\n _labelNodeValue(currentNode) {\n const nodesAtDepth = this._nodes.filter(node => node.depth === currentNode.depth);\n const totalAtDepth = d3.sum(nodesAtDepth, node => node.value);\n const nodeValue = this._formatThousand(currentNode.value);\n const nodePercent = this._formatPercent(currentNode.value / totalAtDepth);\n\n let label = '';\n switch (this._displayValues) {\n case DISPLAY_VALUES.total:\n label = `${nodeValue}`;\n break;\n case DISPLAY_VALUES.percentage:\n label = `${nodePercent}`;\n break;\n case DISPLAY_VALUES.both:\n label = `${nodePercent} - ${nodeValue}`;\n break;\n default:\n break;\n }\n return label;\n };\n\n // ------------------------------ DRAWING -------------------------------\n\n _renderSVG() {\n // BACKGROUND\n this._container.style('background-color', this._background)\n\n // BOUNDS\n this._gBound = this._container.append('g')\n .attr('transform', `translate(${this._marginLeft}, ${this._marginTop})`);\n\n // NODES\n this._svgNode = this._gBound\n .append('g')\n .attr('stroke', '#000')\n .selectAll('.sankey-node')\n .data(this._nodes, node => node.name)\n .join('rect')\n .attr('class', 'sankey-node')\n .attr('id', d => d.name)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('height', d => d.y1 - d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('stroke', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .attr('fill', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .on('mouseover', d => this._highlightOnHover && this._showLinks(d))\n .on('mouseout', _ => this._highlightOnHover && this._showAll());\n\n // LINKS\n this._svgLink = this._gBound\n .append('g')\n .attr('fill', 'none')\n .attr('stroke-opacity', 0.3)\n .selectAll('g')\n .data(this._links, link => `${link.source.name}-${link.target.name}`)\n .join('g')\n .style('mix-blend-mode', 'multiply');\n\n if (this._edgeColor === 'path') this._setLinkGradient()\n\n this._svgLink\n .append('path')\n .attr('class', 'sankey-link')\n .attr('d', d3Sankey.sankeyLinkHorizontal())\n .attr('stroke', \"rgba(182, 185, 196, 1)\")\n .attr('stroke-width', d => Math.max(1, d.width)); \n\n // LABELS\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('y', d => (d.y1 + d.y0) / 2)\n .attr('dy', '0.35em')\n .text(d => d.name);\n\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('font-size', 14)\n .attr('font-weight', '700')\n .attr('y', d => ((d.y1 + d.y0) / 2) + 16)\n .attr('dy', '0.35em')\n .text(d => this._labelNodeValue(d));\n\n this._svgNode\n .append('title')\n .text(d => `${d.name}\\n${this._formatValue(d.value)}`);\n\n this._svgLink\n .append('title')\n .text(d => `${d.source.name} → ${d.target.name}\\n${this._formatValue(d.value)}`);\n }\n\n\n // ----------------------------------------------------------------------- \n // ------------------------------ API ------------------------------\n // ----------------------------------------------------------------------- \n\n data(_) {\n return arguments.length ? (this._data = _, this) : this._data;\n };\n\n width(_) {\n return arguments.length ? (this._width = +_, this) : this._width;\n };\n\n height(_) {\n return arguments.length ? (this._height = +_, this) : this._height;\n };\n\n align(_) {\n return arguments.length ? (this._sankeyAlignType = _, this) : this._sankeyAlignType;\n }\n\n colorScheme(_) {\n return arguments.length ? (this._colorScheme = _, this) : this._colorScheme;\n }\n\n colorArray(_) {\n return arguments.length ? (this._colorArray = _, this) : this._colorArray;\n }\n\n edgeColor(_) {\n return arguments.length ? (this._edgeColor = _, this) : this._edgeColor;\n }\n\n displayValues(_) {\n return arguments.length ? (this._displayValues = _, this) : this._displayValues;\n }\n\n highlightOnHover(_) {\n return arguments.length ? (this._highlightOnHover = _, this) : this._highlightOnHover;\n }\n\n render() {\n if (!this._validate()) {\n // no graph data\n }\n else {\n this._init();\n this._renderSVG()\n }\n return this;\n }\n}\n","// @ts-nocheck\nimport React from 'react';\nimport { Icon } from '@grafana/ui';\n\nexport const ErrorMessage = ({ message }) => ( \n

\n

\n \n
{message}
\n
\n

\n)\n\nconst panelStyles = {\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n}\n\nconst containerStyles = {\n padding: '15px 20px',\n marginBottom: '4px',\n position: 'relative',\n color: 'rgb(255, 255, 255)',\n textShadow: 'rgb(0 0 0 / 20%) 0px 1px 0px',\n borderRadius: '3px',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n background: 'linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))'\n}\n\nconst messageStyles = {\n marginLeft: 10\n}\n","const SHOULD_LOG = true;\n\nexport const logger = fnLogger();\n\nfunction fnLogger(shouldLog = SHOULD_LOG) {\n if (!shouldLog) {\n return {\n warn: (..._: any[]) => undefined,\n error: (..._: any[]) => undefined,\n log: (..._: any[]) => undefined,\n };\n }\n\n return {\n warn: console.warn,\n error: console.error,\n log: console.log,\n };\n}\n","// @ts-nocheck\nimport React, { useState, useEffect } from 'react';\nimport * as d3 from 'd3';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyOptions } from 'types';\nimport { Sankey } from 'Sankey'\nimport { ErrorMessage } from 'Error'\nimport { logger } from 'fn-logger';\n\ninterface Props extends PanelProps {}\n\nexport const SankeyPanel: React.FC = ({ options, data, width, height }) => {\n // ------------------------ CHART CONSTANTS -----------------------\n const CHART_REQUIRED_FIELDS = { source: 'source', target: 'target', value: 'value' };\n\n // ------------------------ ERROR MESSAGES ------------------------\n const requiredFieldsMsg = `Required fields not present: ${Object.keys(CHART_REQUIRED_FIELDS).join(', ')}`;\n const fieldTypeMsg = `Fields should have the following types: source (string), target (string), value (numeric)`;\n\n // ------------------------- REACT HOOKS --------------------------\n const [ error, setError ] = useState({ isError: false, message: '' })\n const [ graph, setGraph ] = useState({ nodes: [], links: [] })\n\n useEffect(() => {\n if (data.error) {\n logger.warn('[FN] Sankey data error.',{data, error: data.error})\n }\n\n data.error\n ?\n setError({isError: true, message: data.error.message})\n :\n setGraph(buildGraph())\n }, [data])\n\n // ------------------------- DATA ACQUISITION -------------------------\n const validate = (sources, targets, values) => {\n let isValid = true;\n\n // REQUIRED FIELDS\n if (!(sources && targets && values)) {\n setError({ isError: true, message: requiredFieldsMsg })\n return isValid = false;\n }\n\n // FIELD TYPES\n const sourcesString = sources.every(d => typeof d === 'string')\n const targetsString = targets.every(d => typeof d === 'string')\n const valuesNumeric = values.every(d => typeof d === 'number')\n\n if (!(sourcesString && targetsString && valuesNumeric)) {\n setError({ isError: true, message: fieldTypeMsg })\n return isValid = false;\n }\n\n setError({});\n\n return isValid;\n }\n\n const buildGraph = () => {\n const frame = data.series[0];\n\n const sourceAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.source);\n const targetAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.target);\n const valueAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.value);\n\n const sources = sourceAccesor?.values.toArray();\n const targets = targetAccesor?.values.toArray();\n const values = valueAccesor?.values.toArray();\n\n const isValid = validate(sources, targets, values);\n if (!isValid) {return}\n\n const zip = d3.zip(sources, targets, values);\n\n const nodes = Array.from(new Set(sources.concat(targets))).map(node => ({ name: node }));\n const links = zip.map(d => ({ source: d[0], target: d[1], value: +d[2].toFixed(2) }));\n const graph = { nodes, links };\n\n return graph\n }\n\n // ------------------------------- CHART ------------------------------\n const chart = svg => {\n const sankey = new Sankey(svg)\n .width(width)\n .height(height)\n .align(options.align)\n .edgeColor(options.edgeColor)\n .colorScheme(options.colorScheme)\n .displayValues(options.displayValues)\n .highlightOnHover(options.highlightOnHover)\n .colorArray(options.colorArray)\n .data(graph)\n\n try {\n sankey.render();\n } catch (renderError) {\n logger.warn('[FN] Sankey render error.',{renderError, graph})\n\n setError({isError: true, message: renderError.message})\n }\n };\n\n return (error.isError ?\n \n :\n {\n d3.select(node)\n .selectAll('*')\n .remove();\n d3.select(node).call(chart);\n }}\n />\n );\n};\n","// NOTE: implementation of toDataFrame: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/dataframe/processDataFrame.ts\nimport { toDataFrame, FieldType, ArrayVector, Field } from '@grafana/data';\nimport { logger } from 'fn-logger';\n\nimport { SankeyOptionsFn } from 'types-fn';\n\nexport function transformFnData(): Required['transformFn'] {\n return ({ series, ...other }) => {\n const transformedSeries = series.map((data) => {\n return toDataFrame({ ...data, fields: data.fields.map(mapField()) });\n });\n\n return {\n series: transformedSeries,\n ...other,\n };\n };\n}\n\nconst SANKEY_FIELD_NAMES = ['source', 'target', 'value'];\n\n// @ts-ignore\nfunction mapField

() {\n return (field: Field

, _: number, __: Array>) => {\n const isSankeyField = SANKEY_FIELD_NAMES.includes(field.name);\n\n const isArrayVector = field.values instanceof ArrayVector || typeof field.values?.toArray === 'function';\n const isArray = Array.isArray(field.values);\n\n if (!isSankeyField || !field.values || (!isArray && !isArrayVector)) {\n return field;\n }\n\n const values = isArrayVector ? field.values.toArray() : isArray ? field.values : null;\n\n if (values === null) {\n logger.warn('[FN] Failed to transform sankey data.', 'Values are not an array.');\n\n return {\n ...field,\n values: new ArrayVector([]),\n };\n }\n\n const parsedValues = isSankeyField ? ((values as P[]).map(splitValue())[0] as unknown[]).map(mapToNumber()) : null;\n\n try {\n return {\n ...field,\n type: parsedValues?.every(isNumber()) ? FieldType.number : field.type,\n values: parsedValues ? new ArrayVector(JSON.parse(JSON.stringify(parsedValues))) : values,\n };\n } catch (err) {\n logger.warn('[FN] Failed to transform sankey data.', err instanceof Error ? err.message : String(err));\n\n return {\n ...field,\n type: field.type,\n values: new ArrayVector([]),\n };\n }\n };\n}\n\n// @ts-ignore\nfunction mapToNumber() {\n return (value: V, _: number, __: V[]) => (Number.isNaN(Number(value)) ? value : Number(value));\n}\n\n// @ts-ignore\nfunction splitValue() {\n return (value: V) => (typeof value === 'string' ? value.split('|') : value);\n}\n\n// @ts-ignore\nfunction isNumber() {\n return (value: V) => typeof value === 'number';\n}\n","import { PanelPlugin } from '@grafana/data';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { SankeyPanelFn as SankeyPanel } from './SankeyPanelFn';\n\nexport const plugin = new PanelPlugin(SankeyPanel).setPanelOptions((builder) => {\n return builder\n .addSelect({\n path: 'align',\n name: 'Align',\n defaultValue: 'Justify',\n settings: {\n options: [\n {\n value: 'Justify',\n label: 'Justify',\n },\n {\n value: 'Left',\n label: 'Left',\n },\n {\n value: 'Right',\n label: 'Right',\n },\n {\n value: 'Center',\n label: 'Center',\n },\n ],\n },\n })\n .addTextInput({\n path: 'colorArray',\n name: 'Color Object',\n defaultValue: '',\n })\n .addSelect({\n path: 'colorScheme',\n name: 'Color',\n defaultValue: 'Tableau10',\n settings: {\n options: [\n {\n value: 'Tableau10',\n label: 'Tableau10',\n },\n {\n value: 'Category10',\n label: 'Category10',\n },\n {\n value: 'Accent',\n label: 'Accent',\n },\n {\n value: 'Dark2',\n label: 'Dark2',\n },\n {\n value: 'Paired',\n label: 'Paired',\n },\n {\n value: 'Pastel1',\n label: 'Pastel1',\n },\n {\n value: 'Pastel2',\n label: 'Pastel2',\n },\n {\n value: 'Set1',\n label: 'Set1',\n },\n {\n value: 'Set2',\n label: 'Set2',\n },\n {\n value: 'Set3',\n label: 'Set3',\n },\n ],\n },\n })\n .addSelect({\n path: 'edgeColor',\n name: 'Edge Color',\n defaultValue: 'path',\n settings: {\n options: [\n {\n value: 'path',\n label: 'input-output',\n },\n {\n value: 'input',\n label: 'input',\n },\n {\n value: 'output',\n label: 'output',\n },\n {\n value: 'none',\n label: 'none',\n },\n ],\n },\n })\n .addSelect({\n path: 'displayValues',\n name: 'Display Values',\n defaultValue: 'none',\n settings: {\n options: [\n {\n value: 'total',\n label: 'Totals',\n },\n {\n value: 'percentage',\n label: 'Percentages',\n },\n {\n value: 'both',\n label: 'Both',\n },\n {\n value: 'none',\n label: 'None',\n },\n ],\n },\n })\n .addBooleanSwitch({\n path: 'highlightOnHover',\n name: 'Highlight connections on node hover',\n defaultValue: false,\n });\n});\n","import React, { useMemo, FC } from 'react';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyPanel } from 'SankeyPanel';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { transformFnData } from 'transform-fn-data';\n\nexport interface SankeyPanelFnProps extends PanelProps {}\n\nexport const SankeyPanelFn: FC = ({ data, ...props }) => {\n const transformFn = useMemo(transformFnData, []);\n\n const transformedData = useMemo(() => transformFn(data), [transformFn, data]);\n\n return ;\n};\n"],"sourceRoot":""} \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json b/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json index ed100c1ee1689..621bba580d282 100644 --- a/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json +++ b/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json @@ -8,12 +8,7 @@ "name": "Ismael", "url": "" }, - "keywords": [ - "sankey", - "d3", - "grafana", - "panel" - ], + "keywords": ["sankey", "d3", "grafana", "panel"], "logos": { "small": "img/logo.svg", "large": "img/logo.svg" @@ -30,10 +25,10 @@ ], "screenshots": [], "version": "1.0.0", - "updated": "2022-12-23" + "updated": "2023-01-05" }, "dependencies": { "grafanaVersion": "7.0.x", "plugins": [] } -} \ No newline at end of file +} From 1a9457a86ae953ad82ac620ce711480cb7cf3856 Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Thu, 5 Jan 2023 13:44:56 +0100 Subject: [PATCH 013/101] FN Render filters and time selector, hide loader despite pageNav and sectionNav --- public/app/features/dashboard/containers/DashboardPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index 0d8ac501fc329..744ebf05a59ab 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -393,14 +393,14 @@ export class UnthemedDashboardPage extends PureComponent { render() { const { dashboard, initError, queryParams, isPublic, isFNDashboard, fnLoader } = this.props; const { editPanel, viewPanel, updateScrollTop, pageNav, sectionNav } = this.state; - const kioskMode = !isPublic ? getKioskMode(this.props.queryParams) : KioskMode.Full; + const kioskMode = isFNDashboard ? KioskMode.FN : !isPublic ? getKioskMode(this.props.queryParams) : KioskMode.Full; - if (!dashboard || !pageNav || !sectionNav) { + if (!dashboard ) { return fnLoader ? <>{fnLoader} : ; } const inspectPanel = this.getInspectPanel(); - const showSubMenu = !editPanel && !kioskMode && !this.props.queryParams.editview && dashboard.isSubMenuVisible(); + const showSubMenu = !editPanel && !this.props.queryParams.editview; const toolbar = kioskMode !== KioskMode.Full && !queryParams.editview && (

From 6fc28584b9cdd878e1fd49c9f2429417f9c92352 Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Thu, 5 Jan 2023 13:49:24 +0100 Subject: [PATCH 014/101] FN Remove tenary expressions with explicit booleans in DashNav --- .../features/dashboard/components/DashNav/DashNav.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index 225e1799bcbed..6346aef2642e0 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -286,7 +286,7 @@ export const DashNav = memo((props) => { icon="monitor" onClick={onToggleTVMode} key="tv-button" - isHidden={FNDashboard ? true : false} + isHidden={!!FNDashboard} /> ); @@ -305,7 +305,7 @@ export const DashNav = memo((props) => { icon="panel-add" onClick={onAddPanel} key="button-panel-add" - isHidden={FNDashboard ? true : false} + isHidden={!!FNDashboard} /> ); } @@ -323,7 +323,7 @@ export const DashNav = memo((props) => { onDismiss: hideModal, }); }} - isHidden={FNDashboard ? true : false} + isHidden={!!FNDashboard} /> )} @@ -337,7 +337,7 @@ export const DashNav = memo((props) => { onClick={() => gotoSnapshotOrigin(snapshotUrl)} icon="link" key="button-snapshot" - isHidden={FNDashboard ? true : false} + isHidden={!!FNDashboard} /> ); } @@ -349,7 +349,7 @@ export const DashNav = memo((props) => { icon="cog" onClick={onOpenSettings} key="button-settings" - isHidden={FNDashboard ? true : false} + isHidden={!!FNDashboard} /> ); } From 142eb1219c0cc17b931c83c8dfec9c577de2d1c3 Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Thu, 5 Jan 2023 13:52:21 +0100 Subject: [PATCH 015/101] FN Use optional chaining - keybindingSrv in initDashboard --- public/app/features/dashboard/state/initDashboard.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/public/app/features/dashboard/state/initDashboard.ts b/public/app/features/dashboard/state/initDashboard.ts index 64230f0ed28ec..11cbe4817e021 100644 --- a/public/app/features/dashboard/state/initDashboard.ts +++ b/public/app/features/dashboard/state/initDashboard.ts @@ -252,9 +252,7 @@ export function initDashboard(args: InitDashboardArgs): ThunkResult { dashboard.autoFitPanels(window.innerHeight, queryParams.kiosk); } - if (!config.publicDashboardAccessToken) { - args.keybindingSrv.setupDashboardBindings(dashboard); - } + args.keybindingSrv?.setupDashboardBindings(dashboard); } catch (err) { if (err instanceof Error) { dispatch(notifyApp(createErrorNotification('Dashboard init failed', err))); From 1052c6bd7de0dd64b7520c2046e7286867ca7e87 Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Thu, 5 Jan 2023 13:53:06 +0100 Subject: [PATCH 016/101] FN Set isPublicDashboardView to false --- public/app/fn_dashboard.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/fn_dashboard.ts b/public/app/fn_dashboard.ts index 72f6f088f1155..3110e1b907f72 100644 --- a/public/app/fn_dashboard.ts +++ b/public/app/fn_dashboard.ts @@ -7,7 +7,7 @@ config.featureToggles = { publicDashboards: true, }; -config.isPublicDashboardView = true; +config.isPublicDashboardView = false; // eslint-disable-next-line config.bootData.themePaths = (window as any).fnData?.themePaths; From 8db6785a77571d1a670c609236eff1c0a79241ff Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Thu, 5 Jan 2023 13:59:25 +0100 Subject: [PATCH 017/101] FN Set hiddenVariables in initial FN state --- .../fn-dashboard-page/render-fn-dashboard.tsx | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx index db2ce4be561d5..249be507a95c0 100644 --- a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx @@ -3,7 +3,7 @@ import React, { useEffect, FC, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { locationService as locationSrv, HistoryWrapper } from '@grafana/runtime'; -import { setInitialMountState } from 'app/core/reducers/fn-slice'; +import { FnGlobalState, setInitialMountState } from 'app/core/reducers/fn-slice'; import DashboardPage, { DashboardPageProps } from 'app/features/dashboard/containers/DashboardPage'; import { FnLoggerService } from 'app/fn_logger'; import { DashboardRoutes, StoreState, useSelector } from 'app/types'; @@ -68,19 +68,20 @@ export const RenderFNDashboard: FC = (props) => { }, [firstError, setErrors]); useEffect(() => { - FnLoggerService.log(null, '[FN Grafana] Trying to set initial state...'); - - dispatch( - setInitialMountState({ - FNDashboard: true, - uid, - slug, - mode, - controlsContainer, - pageTitle, - queryParams, - }) - ); + const initialState: FnGlobalState = { + FNDashboard: true, + uid, + slug, + mode, + controlsContainer, + pageTitle, + queryParams, + hiddenVariables, + }; + + FnLoggerService.log(null, '[FN Grafana] Trying to set initial state.', { initialState }); + + dispatch(setInitialMountState(initialState)); // TODO: catch success in redux-thunk way FnLoggerService.log( @@ -92,8 +93,7 @@ export const RenderFNDashboard: FC = (props) => { ); locationService.fnPathnameChange(window.location.pathname, queryParams); - - }, [dispatch, uid, slug, controlsContainer, pageTitle, queryParams, mode]); + }, [dispatch, uid, slug, controlsContainer, pageTitle, queryParams, mode, hiddenVariables]); const dashboardPageProps: DashboardPageProps = useMemo(() => merge({}, DEFAULT_DASHBOARD_PAGE_PROPS, { ...DEFAULT_DASHBOARD_PAGE_PROPS, From 1fca5cdf8329638c43fe0e10e98d8deabec63fe8 Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Thu, 5 Jan 2023 13:59:59 +0100 Subject: [PATCH 018/101] FN Lint RenderFnDashboard --- .../fn-dashboard-page/render-fn-dashboard.tsx | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx index 249be507a95c0..8695f9ad54782 100644 --- a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx @@ -21,7 +21,7 @@ const DEFAULT_DASHBOARD_PAGE_PROPS: Pick = (props) => { - const { - queryParams, - uid, - slug, - mode, - controlsContainer, - pageTitle = '', - setErrors, - fnLoader, - } = props; + const { queryParams, uid, slug, mode, controlsContainer, pageTitle = '', setErrors, fnLoader } = props; const dispatch = useDispatch(); @@ -95,19 +86,23 @@ export const RenderFNDashboard: FC = (props) => { locationService.fnPathnameChange(window.location.pathname, queryParams); }, [dispatch, uid, slug, controlsContainer, pageTitle, queryParams, mode, hiddenVariables]); - const dashboardPageProps: DashboardPageProps = useMemo(() => merge({}, DEFAULT_DASHBOARD_PAGE_PROPS, { - ...DEFAULT_DASHBOARD_PAGE_PROPS, - match: { - params: { - ...props, - }, - }, - location: locationService.getLocation(), - queryParams, - hiddenVariables, - controlsContainer, - fnLoader, - }),[controlsContainer, fnLoader, hiddenVariables, props, queryParams]); + const dashboardPageProps: DashboardPageProps = useMemo( + () => + merge({}, DEFAULT_DASHBOARD_PAGE_PROPS, { + ...DEFAULT_DASHBOARD_PAGE_PROPS, + match: { + params: { + ...props, + }, + }, + location: locationService.getLocation(), + queryParams, + hiddenVariables, + controlsContainer, + fnLoader, + }), + [controlsContainer, fnLoader, hiddenVariables, props, queryParams] + ); return isEmpty(queryParams || {}) ? <>{fnLoader} : ; }; From 19300d8d61cf69bebeccbbf7259b70629be78f47 Mon Sep 17 00:00:00 2001 From: Katarzyna Ziomek-Zdanowicz Date: Thu, 5 Jan 2023 14:00:47 +0100 Subject: [PATCH 019/101] FN Lint create-mfe --- public/app/fn-app/create-mfe.ts | 380 ++++++++++++++++---------------- 1 file changed, 190 insertions(+), 190 deletions(-) diff --git a/public/app/fn-app/create-mfe.ts b/public/app/fn-app/create-mfe.ts index 4dc4be53a45ac..8fcc18f3cece9 100644 --- a/public/app/fn-app/create-mfe.ts +++ b/public/app/fn-app/create-mfe.ts @@ -53,250 +53,250 @@ type DeepPartial = { }; class createMfe { - private static readonly containerSelector = '#grafanaRoot'; + private static readonly containerSelector = '#grafanaRoot'; + + private static readonly logPrefix = '[FN Grafana]'; + + mode: FNDashboardProps['mode']; + static Component: ComponentType; + constructor(readonly props: FNDashboardProps) { + this.mode = props.mode; + } + + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + private static logger = (...args: any[]) => console.log(createMfe.logPrefix, ...args); + + static getLifeCycles(component: ComponentType) { + const lifeCycles: FrameworkLifeCycles = { + bootstrap: this.boot(), + mount: this.mountFnApp(component), + unmount: this.unMountFnApp(), + update: this.updateFnApp(), + afterMount: () => Promise.resolve(), + beforeMount: () => Promise.resolve(), + afterUnmount: () => Promise.resolve(), + beforeUnmount: () => Promise.resolve(), + beforeLoad: () => Promise.resolve(), + }; - private static readonly logPrefix = '[FN Grafana]'; + return lifeCycles; + } - mode: FNDashboardProps['mode']; - static Component: ComponentType; - constructor(readonly props: FNDashboardProps) { - this.mode = props.mode; - } + static create(component: ComponentType) { + return createMfe.getLifeCycles(component); + } - /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ - private static logger = (...args: any[]) => console.log(createMfe.logPrefix, ...args); - - static getLifeCycles(component: ComponentType) { - const lifeCycles: FrameworkLifeCycles = { - bootstrap: this.boot(), - mount: this.mountFnApp(component), - unmount: this.unMountFnApp(), - update: this.updateFnApp(), - afterMount: () => Promise.resolve(), - beforeMount: () => Promise.resolve(), - afterUnmount: () => Promise.resolve(), - beforeUnmount: () => Promise.resolve(), - beforeLoad: () => Promise.resolve(), - }; - - return lifeCycles; - } + static boot() { + return () => fn_app.init(); + } - static create(component: ComponentType) { - return createMfe.getLifeCycles(component); - } + private static toggleTheme = (mode: FNDashboardProps['mode']): GrafanaThemeType.Light | GrafanaThemeType.Dark => + mode === 'dark' ? GrafanaThemeType.Light : GrafanaThemeType.Dark; - static boot() { - return () => fn_app.init(); - } + private static get styleSheetLink() { + const stylesheetLink = document.createElement('link'); + stylesheetLink.rel = 'stylesheet'; - private static toggleTheme = (mode: FNDashboardProps['mode']): GrafanaThemeType.Light | GrafanaThemeType.Dark => - mode === 'dark' ? GrafanaThemeType.Light : GrafanaThemeType.Dark; + return stylesheetLink; + } - private static get styleSheetLink() { - const stylesheetLink = document.createElement('link'); - stylesheetLink.rel = 'stylesheet'; + private static createGrafanaTheme2(mode: FNDashboardProps['mode']) { + config.theme2 = createTheme({ + colors: { + mode, + }, + }); - return stylesheetLink; - } + config.theme2.colors = createFnColors({ mode }); - private static createGrafanaTheme2(mode: FNDashboardProps['mode']) { - config.theme2 = createTheme({ - colors: { - mode, - }, - }); + config.theme2.v1 = getTheme(mode); - config.theme2.colors = createFnColors({ mode }); + config.theme2.v1.colors = config.theme.colors; - config.theme2.v1 = getTheme(mode); + return config.theme2; + } - config.theme2.v1.colors = config.theme.colors; + private static getPartialBootConfigWithTheme(theme2: GrafanaTheme2) { + const partial: DeepPartial = { + theme: theme2.v1, + bootData: { user: { lightTheme: theme2.isLight } }, + }; - return config.theme2; - } + return partial; + } - private static getPartialBootConfigWithTheme(theme2: GrafanaTheme2) { - const partial: DeepPartial = { - theme: theme2.v1, - bootData: { user: { lightTheme: theme2.isLight } }, - }; + private static mergeBootConfigs(bootConfig: GrafanaBootConfig, partialBootConfig: DeepPartial) { + return merge({}, bootConfig, partialBootConfig); + } - return partial; - } + private static publishTheme(theme: GrafanaTheme2) { + appEvents.publish(new ThemeChangedEvent(theme)); + } - private static mergeBootConfigs(bootConfig: GrafanaBootConfig, partialBootConfig: DeepPartial) { - return merge({}, bootConfig, partialBootConfig); - } + // NOTE: based on grafana function: 'toggleTheme' + private static removeThemeLinks(modeToBeTurnedOff: GrafanaThemeType.Light | GrafanaThemeType.Dark, timeout?: number) { + Array.from(document.getElementsByTagName('link')).forEach(createMfe.removeThemeLink(modeToBeTurnedOff, timeout)); + } - private static publishTheme(theme: GrafanaTheme2) { - appEvents.publish(new ThemeChangedEvent(theme)); - } + private static removeThemeLink(modeToBeTurnedOff: FNDashboardProps['mode'], timeout?: number) { + return (link: HTMLLinkElement) => { + if (!link.href?.includes(`build/grafana.${modeToBeTurnedOff}`)) { + return; + } - // NOTE: based on grafana function: 'toggleTheme' - private static removeThemeLinks(modeToBeTurnedOff: GrafanaThemeType.Light | GrafanaThemeType.Dark, timeout?: number) { - Array.from(document.getElementsByTagName('link')).forEach(createMfe.removeThemeLink(modeToBeTurnedOff, timeout)); - } + if (isNull(timeout)) { + link.remove(); - private static removeThemeLink(modeToBeTurnedOff: FNDashboardProps['mode'], timeout?: number) { - return (link: HTMLLinkElement) => { - if (!link.href?.includes(`build/grafana.${modeToBeTurnedOff}`)) { - return; - } + return; + } - if (isNull(timeout)) { - link.remove(); + // Remove existing link after a 500ms to allow new css to load to avoid flickering + // If we add new css at the same time we remove current one the page will be rendered without css + // As the new css file is loading + setTimeout(link.remove, timeout); + }; + } - return; - } + /** + * NOTE: + * If isRuntimeOnly then the stylesheets of the turned off theme are not removed + */ + private static loadFnTheme = (mode: FNDashboardProps['mode'] = GrafanaThemeType.Light, isRuntimeOnly = false) => { + createMfe.logger('Trying to load theme.', { mode }); - // Remove existing link after a 500ms to allow new css to load to avoid flickering - // If we add new css at the same time we remove current one the page will be rendered without css - // As the new css file is loading - setTimeout(link.remove, timeout); - }; - } + const grafanaTheme2 = createMfe.createGrafanaTheme2(mode); - /** - * NOTE: - * If isRuntimeOnly then the stylesheets of the turned off theme are not removed - */ - private static loadFnTheme = (mode: FNDashboardProps['mode'], isRuntimeOnly = false) => { - createMfe.logger('Trying to load theme...', mode); + const partialBootConfigWithTheme = createMfe.getPartialBootConfigWithTheme(grafanaTheme2); - const grafanaTheme2 = createMfe.createGrafanaTheme2(mode); + const bootConfigWithTheme = createMfe.mergeBootConfigs(config, partialBootConfigWithTheme); - const partialBootConfigWithTheme = createMfe.getPartialBootConfigWithTheme(grafanaTheme2); + createMfe.publishTheme(bootConfigWithTheme.theme2); - const bootConfigWithTheme = createMfe.mergeBootConfigs(config, partialBootConfigWithTheme); + if (isRuntimeOnly) { + createMfe.logger('Successfully loaded theme', { mode }); - createMfe.publishTheme(bootConfigWithTheme.theme2); + return; + } - if (isRuntimeOnly) { - createMfe.logger('Successfully loaded theme:', mode); + createMfe.removeThemeLinks(createMfe.toggleTheme(mode)); - return; - } + const newCssLink = createMfe.styleSheetLink; + newCssLink.href = config.bootData.themePaths[mode]; + document.body.appendChild(newCssLink); - createMfe.removeThemeLinks(createMfe.toggleTheme(mode)); + createMfe.logger('Successfully loaded theme.', { mode }); + }; - const newCssLink = createMfe.styleSheetLink; - newCssLink.href = config.bootData.themePaths[mode]; - document.body.appendChild(newCssLink); + private static getContainer(props: FNDashboardProps) { + const parentElement = props.container || document; - createMfe.logger('Successfully loaded theme:', mode); - }; + return parentElement.querySelector(createMfe.containerSelector); + } - private static getContainer(props: FNDashboardProps) { - const parentElement = props.container || document; + static mountFnApp(Component: ComponentType) { + const lifeCycleFn: FrameworkLifeCycles['mount'] = (props: FNDashboardProps) => { + createMfe.logger('Trying to mount grafana...'); - return parentElement.querySelector(createMfe.containerSelector); - } + return new Promise((res, rej) => { + try { + createMfe.loadFnTheme(props.mode); + createMfe.Component = Component; - static mountFnApp(Component: ComponentType) { - const lifeCycleFn: FrameworkLifeCycles['mount'] = (props: FNDashboardProps) => { - createMfe.logger('Trying to mount grafana...'); + createMfe.renderMfeComponent(props, () => { + createMfe.logger('Mounted grafana.', { props }); - return new Promise((res, rej) => { - try { - createMfe.loadFnTheme(props.mode); - createMfe.Component = Component; + return res(true); + }); + } catch (err) { + const message = `[FN Grafana]: Failed to mount grafana. ${err}`; - createMfe.renderMfeComponent(props, () => { - createMfe.logger('Mounted grafana.'); + FnLoggerService.log(null, message); - return res(true); - }); - } catch (err) { - const message = `[FN Grafana]: Failed to mount grafana. ${err}`; + const fnError = new Error(message); - FnLoggerService.log(null, message); + const name: FailedToMountGrafanaErrorName = 'FailedToMountGrafana'; + fnError.name = name; - const fnError = new Error(message); + return rej(fnError); + } + }); + }; - const name: FailedToMountGrafanaErrorName = 'FailedToMountGrafana'; - fnError.name = name; + return lifeCycleFn; + } - return rej(fnError); - } - }); - }; + static unMountFnApp() { + const lifeCycleFn: FrameworkLifeCycles['unmount'] = (props: FNDashboardProps) => { + const container = createMfe.getContainer(props); - return lifeCycleFn; - } + if (container) { + createMfe.logger('Trying to unmount grafana...'); - static unMountFnApp() { - const lifeCycleFn: FrameworkLifeCycles['unmount'] = (props: FNDashboardProps) => { - const container = createMfe.getContainer(props); + ReactDOM.unmountComponentAtNode(container); - if (container) { - createMfe.logger('Trying to unmount grafana...'); + createMfe.logger('Successfully unmounted grafana.'); + } else { + createMfe.logger('Failed to unmount grafana. Container does not exist.'); + } - ReactDOM.unmountComponentAtNode(container); + backendSrv.cancelAllInFlightRequests(); - createMfe.logger('Successfully unmounted grafana.'); - } else { - createMfe.logger('Failed to unmount grafana. Container does not exist.'); - } + return Promise.resolve(!!container); + }; - backendSrv.cancelAllInFlightRequests(); + return lifeCycleFn; + } - return Promise.resolve(!!container); - }; + static updateFnApp() { + const lifeCycleFn: FrameworkLifeCycles['update'] = ({ mode, hiddenVariables }: FNDashboardProps) => { + if (mode) { + createMfe.logger('Trying to update grafana with theme.', { mode }); + /** + * NOTE + * We do not use the "mode" state right now, + * but I believe that as long as we store the "mode, we should update it + */ + updateFNGlobalState('mode', mode); + /** + * NOTE: + * Here happens the theme change. + * + * TODO: + * We could probably made the theme change smoother + * if we use state to update the theme + */ + createMfe.loadFnTheme(mode); + } - return lifeCycleFn; - } + if (hiddenVariables) { + createMfe.logger('Trying to update grafana with hidden variables.', { hiddenVariables }); - static updateFnApp() { - const lifeCycleFn: FrameworkLifeCycles['update'] = (props: FNDashboardProps) => { - createMfe.logger('Trying to update grafana with theme:', props.mode); - - - if (props.mode) { - /** - * NOTE - * We do not use the "mode" state right now, - * but I believe that as long as we store the "mode, we should update it - */ - updateFNGlobalState("mode", props.mode); - /** - * NOTE: - * Here happens the theme change. - * - * TODO: - * We could probably made the theme change smoother - * if we use state to update the theme - */ - createMfe.loadFnTheme(props.mode); - } - - if(props.hiddenVariables){ - updateFNGlobalState("hiddenVariables", props.hiddenVariables); - } - - // NOTE: The false/true value does not change anything - return Promise.resolve(true); - }; - - return lifeCycleFn; - } + updateFNGlobalState('hiddenVariables', hiddenVariables); + } - static renderMfeComponent(props: Partial, onSuccess = noop) { - const { fnGlobalState } = store.getState(); + // NOTE: The false/true value does not change anything + return Promise.resolve(true); + }; - /** - * NOTE: - * It may happen that only partial props are received in arguments. - * Then we should keep the current props that are read them from the state. - */ - const mergedProps = merge({}, fnGlobalState, props) as FNDashboardProps; - const container = createMfe.getContainer(mergedProps) + return lifeCycleFn; + } - ReactDOM.render(React.createElement(createMfe.Component, mergedProps), container, () => { - createMfe.logger('Rendered mfe component.', {mergedProps, container}); - onSuccess(); - }); - } + static renderMfeComponent(props: Partial, onSuccess = noop) { + const { fnGlobalState } = store.getState(); + + /** + * NOTE: + * It may happen that only partial props are received in arguments. + * Then we should keep the current props that are read them from the state. + */ + const mergedProps = merge({}, fnGlobalState, props) as FNDashboardProps; + const container = createMfe.getContainer(mergedProps); + + ReactDOM.render(React.createElement(createMfe.Component, mergedProps), container, () => { + createMfe.logger('Rendered mfe component.', { mergedProps, container }); + onSuccess(); + }); + } } export { createMfe }; From 1e381d687ecc131974704890e747481edb90a58f Mon Sep 17 00:00:00 2001 From: Hardik Shingala <34568645+hdkshingala@users.noreply.github.com> Date: Tue, 10 Jan 2023 16:06:58 +0530 Subject: [PATCH 020/101] Updated SSH Keys (#43) --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f2f0229be62dd..4d94ccae53d52 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -71,7 +71,7 @@ commands: description: opsninja branch to install from fingerprint: type: string - default: 8d:43:0f:09:ed:86:44:23:4f:43:88:29:71:bf:92:e7 # fluxninja/cloud R/O + default: 10:d1:92:4e:2a:55:81:c9:82:c2:74:ce:6d:0e:e8:a8 # fluxninja/cloud R/O description: What SSH identity to use for accessing opsninja repository steps: - add_ssh_keys: @@ -224,7 +224,7 @@ jobs: steps: - add_ssh_keys: fingerprints: - - "7b:4a:f0:04:90:75:93:7a:63:05:3b:18:a0:80:16:0d" # argo-manifests R/W + - "f9:49:04:10:b1:77:16:b0:0e:c0:ba:21:0e:9d:fd:40" # argo-manifests R/W - checkout - asdf_install: cache_name: release From 82e642b0ba0f420cdcd05e47d6fdec3c8da88d40 Mon Sep 17 00:00:00 2001 From: Gurinder Singh <108446046+gurinder39@users.noreply.github.com> Date: Thu, 12 Jan 2023 12:47:36 -0500 Subject: [PATCH 021/101] Time range selector changes (#42) * changed time picker dropdown designs * change time setting button * added dark and light --- .../TimeRangePicker/TimePickerContent.tsx | 104 ++++++++---------- .../TimeRangePicker/TimePickerFooter.tsx | 95 ++++++++-------- .../TimeRangePicker/TimeRangeContent.tsx | 32 ++---- .../TimeZonePicker/TimeZoneDescription.tsx | 9 +- 4 files changed, 114 insertions(+), 126 deletions(-) diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx index 7c8e60d7277f9..3a5f3c06f2e8c 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 { memo, useMemo, useState } from 'react'; import { GrafanaTheme2, isDateTime, rangeUtil, RawTimeRange, TimeOption, TimeRange, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { useStyles2, useTheme2 } from '../../../themes'; +import { stylesFactory, useStyles2, useTheme2 } from '../../../themes'; import { getFocusStyles } from '../../../themes/mixins'; import { t, Trans } from '../../../utils/i18n'; import { FilterInput } from '../../FilterInput/FilterInput'; @@ -79,11 +79,6 @@ export const TimePickerContentWithScreenSize = (props: PropsWithScreenSize) => { return (
- {isFullscreen && ( -
- -
- )} {(!isFullscreen || !hideQuickRanges) && (
@@ -102,6 +97,11 @@ export const TimePickerContentWithScreenSize = (props: PropsWithScreenSize) => {
)} + {isFullscreen && ( +
+ +
+ )}
{!hideTimeZone && isFullscreen && ( { className={styles.container} style={{ height: '100%', - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', + padding: '25px', }} >
@@ -278,54 +275,45 @@ const useTimeOption = (raw: RawTimeRange, quickOptions: TimeOption[]): TimeOptio }, [raw, quickOptions]); }; -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, - display: 'flex', - flexDirection: 'column', - }), - 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: 'auto', - scrollbarWidth: 'thin', - 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', - }), - scrollContent: css({ - overflowY: 'auto', - scrollbarWidth: 'thin', - }), +const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRanges, isContainerTall, isFullscreen) => { + return { + container: css` + background: ${theme.colors.background.primary}; + box-shadow: ${theme.shadows.z3}; + position: absolute; + z-index: ${theme.zIndex.dropdown}; + width: ${isFullscreen ? '546px' : '262px'}; + top: 116%; + border-radius: 2px; + border: 1px solid ${theme.colors.border.weak}; + ${isReversed ? 'left' : 'right'}: 0; + `, + body: css` + display: flex; + flex-direction: row-reverse; + height: ${isContainerTall ? '281px' : '217px'}; + `, + leftSide: css` + display: flex; + flex-direction: column; + border-right: ${isReversed ? 'none' : `1px solid ${theme.colors.border.weak}`}; + width: ${!hideQuickRanges ? '50%' : '100%'}; + overflow: hidden; + order: ${isReversed ? 1 : 0}; + `, + rightSide: css` + width: ${isFullscreen ? '50%' : '100%'}; !important; + border-right: ${isReversed ? `1px solid ${theme.colors.border.weak}` : 'none'}; + display: flex; + flex-direction: column; + `, + timeRangeFilter: css` + padding: ${theme.spacing(1)}; + `, + spacing: css` + margin-top: 16px; + `, + }; }); const getNarrowScreenStyles = (theme: GrafanaTheme2) => ({ diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx index 28b328ed5c3a3..c596ddc9a9acf 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { getTimeZoneInfo, GrafanaTheme2, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { useStyles2 } from '../../../themes'; +import { stylesFactory, useStyles2 } from '../../../themes'; import { t, Trans } from '../../../utils/i18n'; import { Button } from '../../Button'; import { Field } from '../../Forms/Field'; @@ -63,6 +63,8 @@ export const TimePickerFooter = (props: Props) => { return null; } + const fnColor = theme.isDark ? '#8EC4AD' : '#3A785E'; + return (
{
@@ -162,42 +164,45 @@ export const TimePickerFooter = (props: Props) => { ); }; -const getStyle = (theme: GrafanaTheme2) => ({ - container: css({ - borderTop: `1px solid ${theme.colors.border.weak}`, - padding: theme.spacing(1.5), - display: 'flex', - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - }), - editContainer: css({ - borderTop: `1px solid ${theme.colors.border.weak}`, - padding: theme.spacing(1.5), - paddingTop: 0, - 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 = stylesFactory((theme: GrafanaTheme2) => { + return { + container: css` + border-top: 1px solid ${theme.colors.border.weak}; + padding: 11px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + height: 60px; + `, + editContainer: css` + border-top: 1px solid ${theme.colors.border.weak}; + padding: 11px; + justify-content: space-between; + align-items: center; + padding: 7px; + `, + spacer: css` + margin-left: 7px; + `, + timeSettingContainer: css` + padding-top: ${theme.spacing(1)}; + `, + fiscalYearField: css` + margin-bottom: 0px; + `, + timeZoneContainer: css` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + flex-grow: 1; + `, + timeZone: css` + display: flex; + flex-direction: row; + align-items: baseline; + flex-grow: 1; + `, + }; }); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx index 87f5572c586c8..a4e6b15b667d5 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx @@ -195,27 +195,17 @@ export const TimeRangeContent = (props: Props) => { {fyTooltip}
-
- -
+ { const styles = useStyles2(getStyles); const description = useDescription(info); + const { isDark } = useTheme2(); if (!info) { return null; } - return
{description}
; + return ( +
+ {description} +
+ ); }; const useDescription = (info?: TimeZoneInfo): string => { From 867df86146a6209d1524d92044e6fe534b8d70fb Mon Sep 17 00:00:00 2001 From: Kasia <24753130+ziomecka@users.noreply.github.com> Date: Mon, 16 Jan 2023 13:04:12 +0100 Subject: [PATCH 022/101] 7829 Read hiddenVariables, mode, FNDashboard from grfana's state (#44) Co-authored-by: Katarzyna Ziomek-Zdanowicz --- public/app/core/reducers/fn-slice.ts | 86 +++++++++-------- .../dashboard/components/SubMenu/SubMenu.tsx | 10 +- .../components/SubMenu/SubMenuItems.tsx | 6 +- .../dashboard/containers/DashboardPage.tsx | 46 ++++----- public/app/fn-app/create-mfe.ts | 96 +++++++++++-------- .../fn-app/fn-dashboard-page/fn-dashboard.tsx | 90 +++++++++++------ .../fn-dashboard-page/render-fn-dashboard.tsx | 39 +------- public/app/fn-app/types.ts | 2 +- 8 files changed, 205 insertions(+), 170 deletions(-) diff --git a/public/app/core/reducers/fn-slice.ts b/public/app/core/reducers/fn-slice.ts index 57f9d767eec0b..0d9128ade0ae6 100644 --- a/public/app/core/reducers/fn-slice.ts +++ b/public/app/core/reducers/fn-slice.ts @@ -1,8 +1,6 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { WritableDraft } from 'immer/dist/internal'; +import { createSlice, PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit'; import { GrafanaThemeType } from '@grafana/data'; -import { dispatch } from 'app/store/store'; import { AnyObject } from '../../fn-app/types'; @@ -14,17 +12,41 @@ export interface FnGlobalState { controlsContainer: string | null; pageTitle: string; queryParams: AnyObject; - hiddenVariables: string[]; + hiddenVariables: readonly string[]; } -export type UpdateFNGlobalStateAction = PayloadAction<{ - type: keyof FnGlobalState; - payload: FnGlobalState[keyof FnGlobalState]; -}>; +export type UpdateFNGlobalStateAction = PayloadAction>; + +export type SetFnStateAction = PayloadAction>; + +export type FnPropMappedFromState = Extract; +export type FnStateProp = keyof FnGlobalState; + +export type FnPropsMappedFromState = Pick; + +export const fnStateProps: FnStateProp[] = [ + 'FNDashboard', + 'controlsContainer', + 'hiddenVariables', + 'mode', + 'pageTitle', + 'queryParams', + 'slug', + 'uid', +]; + +export const fnPropsMappedFromState: readonly FnPropMappedFromState[] = [ + 'FNDashboard', + 'hiddenVariables', + 'mode', +] as const; const INITIAL_MODE = GrafanaThemeType.Light; -const initialState: FnGlobalState = { +export const FN_STATE_KEY = 'fnGlobalState'; + +export const INITIAL_FN_STATE: FnGlobalState = { + // NOTE: initial value is false FNDashboard: false, uid: '', slug: '', @@ -33,37 +55,25 @@ const initialState: FnGlobalState = { pageTitle: '', queryParams: {}, hiddenVariables: [], -}; +} as const; -const fnSlice = createSlice({ - name: 'fnGlobalState', - initialState, - reducers: { - setInitialMountState: (state, action: PayloadAction>) => { - return { ...state, ...action.payload }; - }, - updateFnState: (state: WritableDraft, action: UpdateFNGlobalStateAction) => { - const { type, payload } = action.payload; - - return { - ...state, - [type]: payload, - }; - }, +const reducers: SliceCaseReducers = { + updateFnState: (state, action: SetFnStateAction) => { + return { ...state, ...action.payload }; + }, + updatePartialFnStates: (state, action: UpdateFNGlobalStateAction) => { + return { + ...state, + ...action.payload, + }; }, +}; + +const fnSlice = createSlice, string>({ + name: FN_STATE_KEY, + initialState: INITIAL_FN_STATE, + reducers, }); -export const { updateFnState, setInitialMountState } = fnSlice.actions; +export const { updatePartialFnStates, updateFnState } = fnSlice.actions; export const fnSliceReducer = fnSlice.reducer; - -export const updateFNGlobalState = ( - type: keyof FnGlobalState, - payload: UpdateFNGlobalStateAction['payload']['payload'] -): void => { - dispatch( - updateFnState({ - type, - payload, - }) - ); -}; diff --git a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx index d208553796e17..4d9af8a0e82dc 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx @@ -4,8 +4,7 @@ import * as React from 'react'; import { connect, MapStateToProps } from 'react-redux'; import { AnnotationQuery, DataQuery, TypedVariableModel, GrafanaTheme2 } from '@grafana/data'; -import { DashboardLink } from '@grafana/schema'; -import { stylesFactory, Themeable2, withTheme2 } from '@grafana/ui'; +import { FnGlobalState } from 'app/core/reducers/fn-slice'; import { StoreState } from '../../../../types'; import { getSubMenuVariables, getVariablesState } from '../../../variables/state/selectors'; @@ -14,16 +13,19 @@ import { DashboardModel } from '../../state'; import { Annotations } from './Annotations'; import { DashboardLinks } from './DashboardLinks'; import { SubMenuItems } from './SubMenuItems'; +import { VariableModel } from 'app/features/variables/types'; +import { Themeable2, stylesFactory, withTheme2 } from '@grafana-ui'; +import { DashboardLink } from '@grafana/schema/dist/esm/index'; interface OwnProps extends Themeable2 { dashboard: DashboardModel; links: DashboardLink[]; annotations: AnnotationQuery[]; - hiddenVariables?: string[]; } interface ConnectedProps { variables: TypedVariableModel[]; + hiddenVariables: FnGlobalState['hiddenVariables']; } interface DispatchProps {} @@ -79,8 +81,10 @@ class SubMenuUnConnected extends PureComponent { const mapStateToProps: MapStateToProps = (state, ownProps) => { const { uid } = ownProps.dashboard; const templatingState = getVariablesState(uid, state); + return { variables: getSubMenuVariables(uid, templatingState.variables), + hiddenVariables: state.fnGlobalState.hiddenVariables, }; }; diff --git a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx index ff6ae2e60204b..51bc71937901a 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx @@ -4,17 +4,19 @@ import { useEffect, useState, FC } from 'react'; import { GrafanaTheme2, TypedVariableModel, VariableHide } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { useStyles2 } from '@grafana/ui'; +import { FnGlobalState } from 'app/core/reducers/fn-slice'; import { PickerRenderer } from '../../../variables/pickers/PickerRenderer'; interface Props { variables: TypedVariableModel[]; readOnly?: boolean; - hiddenVariables?: string[]; + hiddenVariables?: FnGlobalState['hiddenVariables']; } export const SubMenuItems: FC = ({ variables, readOnly, hiddenVariables }) => { const [visibleVariables, setVisibleVariables] = useState([]); + const styles = useStyles2(getStyles); useEffect(() => { setVisibleVariables(variables.filter((state) => state.hide !== VariableHide.hideVariable)); @@ -34,7 +36,7 @@ export const SubMenuItems: FC = ({ variables, readOnly, hiddenVariables } return (
diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index 744ebf05a59ab..bd1195ff81ce6 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -15,6 +15,7 @@ import { createErrorNotification } from 'app/core/copy/appNotification'; import { getKioskMode } from 'app/core/navigation/kiosk'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { ID_PREFIX } from 'app/core/reducers/navBarTree'; +import { FnGlobalState } from 'app/core/reducers/fn-slice'; import { getNavModel } from 'app/core/selectors/navModel'; import { PanelModel } from 'app/features/dashboard/state'; import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; @@ -50,7 +51,10 @@ import 'react-grid-layout/css/styles.css'; import 'react-resizable/css/styles.css'; export type MapStateToDashboardPageProps = MapStateToProps< - Pick & { dashboard: ReturnType }, + Pick & { dashboard: ReturnType } & Pick< + FnGlobalState, + 'FNDashboard' + >, OwnProps, StoreState >; @@ -70,6 +74,7 @@ export const mapStateToProps: MapStateToDashboardPageProps = (state) => ({ initError: state.dashboard.initError, dashboard: state.dashboard.getModel(), navIndex: state.navIndex, + FNDashboard: state.fnGlobalState.FNDashboard, }); const mapDispatchToProps: MapDispatchToDashboardPageProps = { @@ -84,9 +89,7 @@ const connector = connect(mapStateToProps, mapDispatchToProps); type OwnProps = { isPublic?: boolean; - isFNDashboard?: boolean; controlsContainer?: string | null; - hiddenVariables?: string[]; fnLoader?: ReactNode; }; @@ -167,9 +170,11 @@ export class UnthemedDashboardPage extends PureComponent { componentDidMount() { this.initDashboard(); - const { isPublic, isFNDashboard } = this.props; - if (!isPublic && !isFNDashboard) { - this.forceRouteReloadCounter = (this.props.history.location.state as any)?.routeReloadCounter || 0; + + const { isPublic, FNDashboard } = this.props; + + if (!isPublic && !FNDashboard) { + this.forceRouteReloadCounter = (this.props.history.location?.state as any)?.routeReloadCounter || 0; } } @@ -183,7 +188,7 @@ export class UnthemedDashboardPage extends PureComponent { } initDashboard() { - const { dashboard, isPublic, match, queryParams, isFNDashboard } = this.props; + const { dashboard, isPublic, match, queryParams, FNDashboard } = this.props; if (dashboard) { this.closeDashboard(); @@ -196,7 +201,7 @@ export class UnthemedDashboardPage extends PureComponent { urlFolderUid: queryParams.folderUid, panelType: queryParams.panelType, routeName: this.props.route.routeName, - fixUrl: !isPublic && !isFNDashboard, + fixUrl: !isPublic && !FNDashboard, accessToken: match.params.accessToken, keybindingSrv: this.context.keybindings, }); @@ -206,13 +211,13 @@ export class UnthemedDashboardPage extends PureComponent { } componentDidUpdate(prevProps: Props, prevState: State) { - const { dashboard, match, templateVarsChangedInUrl, isPublic, isFNDashboard } = this.props; + const { dashboard, match, templateVarsChangedInUrl, isPublic, FNDashboard } = this.props; if (!dashboard) { return; } - if (!isPublic && !isFNDashboard) { + if (!isPublic && !FNDashboard) { const routeReloadCounter = (this.props.history.location?.state as any)?.routeReloadCounter; if ( @@ -391,11 +396,11 @@ export class UnthemedDashboardPage extends PureComponent { }; render() { - const { dashboard, initError, queryParams, isPublic, isFNDashboard, fnLoader } = this.props; + const { dashboard, initError, queryParams, isPublic, FNDashboard, fnLoader } = this.props; const { editPanel, viewPanel, updateScrollTop, pageNav, sectionNav } = this.state; - const kioskMode = isFNDashboard ? KioskMode.FN : !isPublic ? getKioskMode(this.props.queryParams) : KioskMode.Full; + const kioskMode = FNDashboard ? KioskMode.FN : !isPublic ? getKioskMode(this.props.queryParams) : KioskMode.Full; - if (!dashboard ) { + if (!dashboard) { return fnLoader ? <>{fnLoader} : ; } @@ -406,7 +411,7 @@ export class UnthemedDashboardPage extends PureComponent {
{ className={pageClassName} onSetScrollRef={this.setScrollRef} > - {!isFNDashboard && } + {!FNDashboard && } {initError && } {showSubMenu && (
- +
)} {config.featureToggles.angularDeprecationUI && dashboard.hasAngularPlugins() && dashboard.uid !== null && ( @@ -548,9 +548,9 @@ export class UnthemedDashboardPage extends PureComponent { } function updateStatePageNavFromProps(props: Props, state: State): State { - const { dashboard, isFNDashboard } = props; + const { dashboard, FNDashboard } = props; - if (!dashboard || isFNDashboard) { + if (!dashboard || FNDashboard) { return state; } diff --git a/public/app/fn-app/create-mfe.ts b/public/app/fn-app/create-mfe.ts index 8fcc18f3cece9..09c1084dba386 100644 --- a/public/app/fn-app/create-mfe.ts +++ b/public/app/fn-app/create-mfe.ts @@ -4,24 +4,30 @@ declare let __webpack_public_path__: string; window.__grafana_public_path__ = __webpack_public_path__.substring(0, __webpack_public_path__.lastIndexOf('build/')) || __webpack_public_path__; -import { isNull, merge, noop } from 'lodash'; +import { isNull, merge, noop, omit, pick } from 'lodash'; import React, { ComponentType } from 'react'; import ReactDOM from 'react-dom'; import { createTheme, GrafanaThemeType } from '@grafana/data'; +import { createFnColors } from '@grafana/data/src/themes/fnCreateColors'; +import { GrafanaTheme2 } from '@grafana/data/src/themes/types'; import { ThemeChangedEvent } from '@grafana/runtime'; +import { GrafanaBootConfig } from '@grafana/runtime/src/config'; import { getTheme } from '@grafana/ui'; import appEvents from 'app/core/app_events'; import config from 'app/core/config'; -import { updateFNGlobalState } from 'app/core/reducers/fn-slice'; +import { + FnGlobalState, + updatePartialFnStates, + updateFnState, + INITIAL_FN_STATE, + FnPropMappedFromState, + fnStateProps, +} from 'app/core/reducers/fn-slice'; import { backendSrv } from 'app/core/services/backend_srv'; import fn_app from 'app/fn_app'; import { FnLoggerService } from 'app/fn_logger'; -import { store } from 'app/store/store'; - -import { createFnColors } from '../../../packages/grafana-data/src/themes/fnCreateColors'; -import { GrafanaTheme2 } from '../../../packages/grafana-data/src/themes/types'; -import { GrafanaBootConfig } from '../../../packages/grafana-runtime/src/config'; +import { dispatch } from 'app/store/store'; import { FNDashboardProps, FailedToMountGrafanaErrorName } from './types'; @@ -30,22 +36,22 @@ import { FNDashboardProps, FailedToMountGrafanaErrorName } from './types'; * Qiankun expects Promise. Otherwise warnings are logged and life cycle hooks do not work */ /* eslint-disable-next-line */ -export declare type LifeCycleFn = (app: any, global: typeof window) => Promise; +export declare type LifeCycleFn = (app: any, global: typeof window) => Promise; /** * NOTE: single-spa and qiankun lifeCycles */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ -export declare type FrameworkLifeCycles = { - beforeLoad: LifeCycleFn | Array>; - beforeMount: LifeCycleFn | Array>; - afterMount: LifeCycleFn | Array>; - beforeUnmount: LifeCycleFn | Array>; - afterUnmount: LifeCycleFn | Array>; - bootstrap: LifeCycleFn | Array>; - mount: LifeCycleFn | Array>; - unmount: LifeCycleFn | Array>; - update: LifeCycleFn | Array>; +export declare type FrameworkLifeCycles = { + beforeLoad: LifeCycleFn | LifeCycleFn[]; + beforeMount: LifeCycleFn | LifeCycleFn[]; + afterMount: LifeCycleFn | LifeCycleFn[]; + beforeUnmount: LifeCycleFn | LifeCycleFn[]; + afterUnmount: LifeCycleFn | LifeCycleFn[]; + bootstrap: LifeCycleFn | LifeCycleFn[]; + mount: LifeCycleFn | LifeCycleFn[]; + unmount: LifeCycleFn | LifeCycleFn[]; + update: LifeCycleFn | LifeCycleFn[]; }; type DeepPartial = { @@ -58,7 +64,7 @@ class createMfe { private static readonly logPrefix = '[FN Grafana]'; mode: FNDashboardProps['mode']; - static Component: ComponentType; + static Component: ComponentType>; constructor(readonly props: FNDashboardProps) { this.mode = props.mode; } @@ -66,7 +72,7 @@ class createMfe { /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ private static logger = (...args: any[]) => console.log(createMfe.logPrefix, ...args); - static getLifeCycles(component: ComponentType) { + static getLifeCycles(component: ComponentType>) { const lifeCycles: FrameworkLifeCycles = { bootstrap: this.boot(), mount: this.mountFnApp(component), @@ -82,7 +88,7 @@ class createMfe { return lifeCycles; } - static create(component: ComponentType) { + static create(component: ComponentType>) { return createMfe.getLifeCycles(component); } @@ -193,7 +199,7 @@ class createMfe { return parentElement.querySelector(createMfe.containerSelector); } - static mountFnApp(Component: ComponentType) { + static mountFnApp(Component: ComponentType>) { const lifeCycleFn: FrameworkLifeCycles['mount'] = (props: FNDashboardProps) => { createMfe.logger('Trying to mount grafana...'); @@ -202,6 +208,16 @@ class createMfe { createMfe.loadFnTheme(props.mode); createMfe.Component = Component; + const initialState: FnGlobalState = { + ...INITIAL_FN_STATE, + FNDashboard: true, + ...pick(props, ...fnStateProps), + }; + + FnLoggerService.log(null, '[FN Grafana] Dispatching initial state.', { initialState }); + + dispatch(updateFnState(initialState)); + createMfe.renderMfeComponent(props, () => { createMfe.logger('Mounted grafana.', { props }); @@ -256,7 +272,11 @@ class createMfe { * We do not use the "mode" state right now, * but I believe that as long as we store the "mode, we should update it */ - updateFNGlobalState('mode', mode); + dispatch( + updatePartialFnStates({ + mode, + }) + ); /** * NOTE: * Here happens the theme change. @@ -271,7 +291,11 @@ class createMfe { if (hiddenVariables) { createMfe.logger('Trying to update grafana with hidden variables.', { hiddenVariables }); - updateFNGlobalState('hiddenVariables', hiddenVariables); + dispatch( + updatePartialFnStates({ + hiddenVariables, + }) + ); } // NOTE: The false/true value does not change anything @@ -281,21 +305,17 @@ class createMfe { return lifeCycleFn; } - static renderMfeComponent(props: Partial, onSuccess = noop) { - const { fnGlobalState } = store.getState(); + static renderMfeComponent(props: FNDashboardProps, onSuccess = noop) { + const container = createMfe.getContainer(props); - /** - * NOTE: - * It may happen that only partial props are received in arguments. - * Then we should keep the current props that are read them from the state. - */ - const mergedProps = merge({}, fnGlobalState, props) as FNDashboardProps; - const container = createMfe.getContainer(mergedProps); - - ReactDOM.render(React.createElement(createMfe.Component, mergedProps), container, () => { - createMfe.logger('Rendered mfe component.', { mergedProps, container }); - onSuccess(); - }); + ReactDOM.render( + React.createElement(createMfe.Component, omit(props, 'hiddenVariables', 'FNDashboard')), + container, + () => { + createMfe.logger('Created mfe component.', { props, container }); + onSuccess(); + } + ); } } diff --git a/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx index a001bc33db882..e861fe9ae1545 100644 --- a/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx @@ -1,8 +1,18 @@ +import { pick } from 'lodash'; import { parse as parseQueryParams } from 'query-string'; import React, { FC, Suspense, useMemo } from 'react'; import { lazily } from 'react-lazily'; +import { connect, MapStateToProps } from 'react-redux'; import { useLocation } from 'react-router-dom'; +import { + FnGlobalState, + FN_STATE_KEY, + FnPropMappedFromState, + fnPropsMappedFromState, + FnPropsMappedFromState, +} from 'app/core/reducers/fn-slice'; + import { FNDashboardProps } from '../types'; import { RenderPortal } from '../utils'; @@ -10,39 +20,61 @@ const { RenderFNDashboard } = lazily(() => import('./render-fn-dashboard')); const { FnAppProvider } = lazily(() => import('../fn-app-provider')); const { AngularRoot } = lazily(() => import('../../angular/AngularRoot')); -export const FNDashboard: FC = (props) => ( - {props.fnLoader}}> - -
- - -
-
-
-); - -export const DashboardPortal: FC = (props) =>{ +type FNDashboardComponentProps = Omit; + +export const FNDashboard: FC = (props) => { + return ( + {props.fnLoader}}> + +
+ + +
+
+
+ ); +}; + +function mapStateToProps(): MapStateToProps< + FnPropsMappedFromState, + Omit, + { [K in typeof FN_STATE_KEY]: FnGlobalState } +> { + return ({ fnGlobalState }) => pick(fnGlobalState, ...fnPropsMappedFromState); +} + +export const DashboardPortalComponent: FC = (props) => { const location = useLocation(); - const portal = useMemo(() =>{ + const content = useMemo(() => { + if (!props.FNDashboard) { + // TODO Use no data + return null; + } + const { search } = location; const queryParams = parseQueryParams(search); - const { dashboardUID, slug } = queryParams + const { dashboardUID: uid, slug } = queryParams as { dashboardUID?: string; slug?: string }; - const newProps: FNDashboardProps = { - ...props, - uid: dashboardUID as string, - slug: slug as string, - queryParams, + if (!uid || !slug) { + // TODO Use no data + return null; } - - return dashboardUID &&( - - - - ) - },[location, props]) - - return <>{portal} -} + + return ( + + ); + }, [location, props]); + + return {content}; +}; + +export const DashboardPortal = connect(mapStateToProps())(DashboardPortalComponent); diff --git a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx index 8695f9ad54782..739b698e741c3 100644 --- a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx @@ -1,27 +1,22 @@ import { merge, isEmpty, isFunction } from 'lodash'; import React, { useEffect, FC, useMemo } from 'react'; -import { useDispatch } from 'react-redux'; import { locationService as locationSrv, HistoryWrapper } from '@grafana/runtime'; -import { FnGlobalState, setInitialMountState } from 'app/core/reducers/fn-slice'; import DashboardPage, { DashboardPageProps } from 'app/features/dashboard/containers/DashboardPage'; -import { FnLoggerService } from 'app/fn_logger'; import { DashboardRoutes, StoreState, useSelector } from 'app/types'; import { FNDashboardProps } from '../types'; const locationService = locationSrv as HistoryWrapper; -const DEFAULT_DASHBOARD_PAGE_PROPS: Pick & { +const DEFAULT_DASHBOARD_PAGE_PROPS: Pick & { match: Pick; } = { - isFNDashboard: true, match: { isExact: true, path: '/d/:uid/:slug?', url: '', }, - history: {} as DashboardPageProps['history'], route: { routeName: DashboardRoutes.Normal, @@ -32,9 +27,7 @@ const DEFAULT_DASHBOARD_PAGE_PROPS: Pick = (props) => { - const { queryParams, uid, slug, mode, controlsContainer, pageTitle = '', setErrors, fnLoader } = props; - - const dispatch = useDispatch(); + const { queryParams, controlsContainer, setErrors, fnLoader, hiddenVariables } = props; const firstError = useSelector((state: StoreState) => { const { appNotifications } = state; @@ -42,8 +35,6 @@ export const RenderFNDashboard: FC = (props) => { return Object.values(appNotifications.byId).find(({ severity }) => severity === 'error'); }); - const hiddenVariables = useSelector(({ fnGlobalState: { hiddenVariables } }: StoreState) => hiddenVariables); - /** * NOTE: * Grafana renders notifications in StoredNotifications component. @@ -59,32 +50,8 @@ export const RenderFNDashboard: FC = (props) => { }, [firstError, setErrors]); useEffect(() => { - const initialState: FnGlobalState = { - FNDashboard: true, - uid, - slug, - mode, - controlsContainer, - pageTitle, - queryParams, - hiddenVariables, - }; - - FnLoggerService.log(null, '[FN Grafana] Trying to set initial state.', { initialState }); - - dispatch(setInitialMountState(initialState)); - - // TODO: catch success in redux-thunk way - FnLoggerService.log( - null, - '[FN Grafana] Successfully set initial state.', - locationService.getLocation(), - locationService.getHistory, - 'location params' - ); - locationService.fnPathnameChange(window.location.pathname, queryParams); - }, [dispatch, uid, slug, controlsContainer, pageTitle, queryParams, mode, hiddenVariables]); + }, [queryParams]); const dashboardPageProps: DashboardPageProps = useMemo( () => diff --git a/public/app/fn-app/types.ts b/public/app/fn-app/types.ts index d3b2ee934712a..37e1143ff4492 100644 --- a/public/app/fn-app/types.ts +++ b/public/app/fn-app/types.ts @@ -30,6 +30,6 @@ export interface FNDashboardProps { controlsContainer: string; isLoading: (isLoading: boolean) => void; setErrors: (errors?: { [K: number | string]: string }) => void; - hiddenVariables: string[]; + hiddenVariables: readonly string[]; container?: HTMLElement | null; } From ddde79602df24739fab8e80a63a1bce2daa8dba2 Mon Sep 17 00:00:00 2001 From: Kasia <24753130+ziomecka@users.noreply.github.com> Date: Tue, 17 Jan 2023 13:42:57 +0100 Subject: [PATCH 023/101] Add tool versions (#45) Co-authored-by: Katarzyna Ziomek-Zdanowicz --- .tool-versions | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .tool-versions diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000000000..e77e0a05ef04d --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +gcloud 395.0.0 +python 3.10.6 From c646c869c6cb8d6d42834cf9a86096595bb0164a Mon Sep 17 00:00:00 2001 From: Hardik Shingala <34568645+hdkshingala@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:33:24 +0530 Subject: [PATCH 024/101] Added support for updating nightly environment (#46) --- .circleci/config.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4d94ccae53d52..fd57a2257c31f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -252,6 +252,7 @@ workflows: name: image-build-grafana-alpine image: cf-fn/grafana - update-environment: + name: update-demo-environment filters: branches: only: @@ -261,6 +262,17 @@ workflows: environment-path: environments/demo/ component: grafana update: images + - update-environment: + name: update-nightly-environment + filters: + branches: + only: + - fluxninja_micro_frontends + requires: + - image-build-grafana-alpine + environment-path: environments/nightly/ + component: grafana + update: images release-components: when: From b4ed45845d2ec2c37789ad4290aeaf195117e592 Mon Sep 17 00:00:00 2001 From: Kasia <24753130+ziomecka@users.noreply.github.com> Date: Thu, 19 Jan 2023 22:35:56 +0100 Subject: [PATCH 025/101] 7911 Add graphql datasource plugin (#47) * 7911 Update FN_README * 7911 Add graphql plugin * 7911 Add graphql plugin Co-authored-by: Katarzyna Ziomek-Zdanowicz --- FN_README.md | 12 +- .../backendplugin/coreplugin/registry.go | 1 + .../app/features/plugins/built_in_plugins.ts | 3 + .../ConfigEditor.tsx | 20 + .../fifemon-graphql-datasource/DataSource.ts | 356 +++++++++++++++++ .../FN_DataSource.ts | 364 ++++++++++++++++++ .../GraphQLAnnotationsQueryCtrl.tsx | 5 + .../QueryEditor.tsx | 110 ++++++ .../VariableQueryEditor.tsx | 47 +++ .../fifemon-graphql-datasource/img/README | 4 + .../img/db_arrivals.png | Bin 0 -> 104030 bytes .../img/db_arrivals_annotations.png | Bin 0 -> 64539 bytes .../img/github_security_advisories.png | Bin 0 -> 137186 bytes .../fifemon-graphql-datasource/img/logo.svg | 71 ++++ .../fifemon-graphql-datasource/module.test.ts | 5 + .../fifemon-graphql-datasource/module.ts | 13 + .../partials/annotations.editor.html | 74 ++++ .../fifemon-graphql-datasource/plugin.json | 36 ++ .../fifemon-graphql-datasource/types.ts | 58 +++ .../fifemon-graphql-datasource/util.test.ts | 51 +++ .../fifemon-graphql-datasource/util.ts | 23 ++ 21 files changed, 1252 insertions(+), 1 deletion(-) create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/ConfigEditor.tsx create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/DataSource.ts create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/GraphQLAnnotationsQueryCtrl.tsx create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/QueryEditor.tsx create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/VariableQueryEditor.tsx create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/img/README create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/img/db_arrivals.png create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/img/db_arrivals_annotations.png create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/img/github_security_advisories.png create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/img/logo.svg create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/module.test.ts create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/module.ts create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/partials/annotations.editor.html create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/plugin.json create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/types.ts create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/util.test.ts create mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/util.ts diff --git a/FN_README.md b/FN_README.md index a3b7f9eed6c07..01e43147d5ac7 100644 --- a/FN_README.md +++ b/FN_README.md @@ -3,12 +3,22 @@ ## How to work with it? We created our fork of [snakey-panel](https://github.com/IsmaelMasharo/sankey-panel) ---> [our fork](https://github.com/fluxninja/sankey-panel) and if we want to add some changes to it we need to: + - git clone our fork - add changes we want - build plugin using `yarn build` (if you want to test something use `yarn dev` because the normal build removes all console.logs) - copy-paste builded version of plugin into grafana `public/app/plugins/panel/sankey-panel-0.5.0` - refresh grafana +# [Grafadruid-druid datasource plugin](./public/app/plugins/datasource//grafadruid-druid-datasource/) + +https://github.com/grafadruid/druid-grafana/tree/master/src + +# [Graphql datasource plugin](./public/app/plugins//datasource//fifemon-graphql-datasource/) + +https://github.com/fifemon/graphql-datasource/tree/v1.3.0/src + +Release: v1.3.0 # Troubleshooting @@ -18,11 +28,11 @@ Smart IDEs (such as VSCode or IntelliJ) require special configuration for TypeSc A collection of settings for each editor can be found under the (link)[https://yarnpkg.com/getting-started/editor-sdks#vscode] Generally speaking: the editor SDKs and settings can be generated using `yarn dlx @yarnpkg/sdks` (or yarn sdks if you added @yarnpkg/sdks to your dependencies): + - Use yarn sdks vscode vim to generate both the base SDKs and the settings for the specified supported editors. - Use yarn sdks base to generate the base SDKs and then manually tweak the configuration of unsupported editors. - Use yarn sdks to update all installed SDKs and editor settings. - ### VSCode To support features like go-to-definition a plugin like ZipFS is needed. diff --git a/pkg/plugins/backendplugin/coreplugin/registry.go b/pkg/plugins/backendplugin/coreplugin/registry.go index a65ce81905f8d..aafbb44da15a0 100644 --- a/pkg/plugins/backendplugin/coreplugin/registry.go +++ b/pkg/plugins/backendplugin/coreplugin/registry.go @@ -47,6 +47,7 @@ const ( Loki = "loki" OpenTSDB = "opentsdb" Druid = "grafadruid-druid-datasource" + Graphql = "fifemon-graphql-datasource" Prometheus = "prometheus" Tempo = "tempo" TestData = "grafana-testdata-datasource" diff --git a/public/app/features/plugins/built_in_plugins.ts b/public/app/features/plugins/built_in_plugins.ts index 007d55f165eca..4b8547c0afe3f 100644 --- a/public/app/features/plugins/built_in_plugins.ts +++ b/public/app/features/plugins/built_in_plugins.ts @@ -21,6 +21,8 @@ const postgresPlugin = async () => await import(/* webpackChunkName: "postgresPlugin" */ 'app/plugins/datasource/postgres/module'); const grafadruidDruidDatasourcePlugin = async () => await import(/* webpackChunkName: "druidPlugin" */ 'app/plugins/datasource/grafadruid-druid-datasource/module'); +const fifemonGraphqlDatasourcePlugin = async () => + await import(/* webpackChunkName: "graphqlPlugin" */ 'app/plugins/datasource/fifemon-graphql-datasource/module'); const prometheusPlugin = async () => await import(/* webpackChunkName: "prometheusPlugin" */ 'app/plugins/datasource/prometheus/module'); const mssqlPlugin = async () => @@ -92,6 +94,7 @@ const builtInPlugins: any = { 'app/plugins/datasource/postgres/module': postgresPlugin, 'app/plugins/datasource/mssql/module': mssqlPlugin, 'app/plugins/datasource/grafadruid-druid-datasource/module': grafadruidDruidDatasourcePlugin, + 'app/plugins/datasource/fifemon-graphql-datasource/module': fifemonGraphqlDatasourcePlugin, 'app/plugins/datasource/prometheus/module': prometheusPlugin, 'app/plugins/datasource/testdata/module': testDataDSPlugin, 'app/plugins/datasource/cloud-monitoring/module': cloudMonitoringPlugin, diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/ConfigEditor.tsx b/public/app/plugins/datasource/fifemon-graphql-datasource/ConfigEditor.tsx new file mode 100644 index 0000000000000..0ab28977f86b6 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/ConfigEditor.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { DataSourceHttpSettings } from '@grafana/ui'; +import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; +import { MyDataSourceOptions } from './types'; + +export type Props = DataSourcePluginOptionsEditorProps; +export const ConfigEditor = (props: Props) => { + const { options, onOptionsChange } = props; + + return ( + <> + + + ); +}; diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/DataSource.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/DataSource.ts new file mode 100644 index 0000000000000..47803b184cc02 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/DataSource.ts @@ -0,0 +1,356 @@ +import defaults from 'lodash/defaults'; + +import { + AnnotationEvent, + AnnotationQueryRequest, + DataQueryRequest, + DataQueryResponse, + DataSourceApi, + MetricFindValue, + DataSourceInstanceSettings, + ScopedVars, + TimeRange, +} from '@grafana/data'; + +import { + MyQuery, + MyDataSourceOptions, + defaultQuery, + MyVariableQuery, + MultiValueVariable, + TextValuePair, +} from './types'; +import { dateTime, MutableDataFrame, FieldType, DataFrame } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; +import _ from 'lodash'; +import { isEqual } from 'lodash'; +import { flatten, isRFC3339_ISO6801 } from './util'; + +const supportedVariableTypes = ['constant', 'custom', 'query', 'textbox']; + +export class DataSource extends DataSourceApi { + basicAuth: string | undefined; + withCredentials: boolean | undefined; + url: string | undefined; + + constructor(instanceSettings: DataSourceInstanceSettings, private backendSrv: any) { + super(instanceSettings); + this.basicAuth = instanceSettings.basicAuth; + this.withCredentials = instanceSettings.withCredentials; + this.url = instanceSettings.url; + } + + private request(data: string) { + const options: any = { + url: this.url, + method: 'POST', + data: { + query: data, + }, + }; + + if (this.basicAuth || this.withCredentials) { + options.withCredentials = true; + } + if (this.basicAuth) { + options.headers = { + Authorization: this.basicAuth, + }; + } + + return this.backendSrv.datasourceRequest(options); + } + + private postQuery(query: Partial, payload: string) { + return this.request(payload) + .then((results: any) => { + return { query, results }; + }) + .catch((err: any) => { + if (err.data && err.data.error) { + throw { + message: 'GraphQL error: ' + err.data.error.reason, + error: err.data.error, + }; + } + + throw err; + }); + } + + private createQuery(query: MyQuery, range: TimeRange | undefined, scopedVars: ScopedVars | undefined = undefined) { + let payload = getTemplateSrv().replace(query.queryText, { + ...scopedVars, + timeFrom: { text: 'from', value: range?.from.valueOf() }, + timeTo: { text: 'to', value: range?.to.valueOf() }, + }); + + //console.log(payload); + return this.postQuery(query, payload); + } + private static getDocs(resultsData: any, dataPath: string): any[] { + if (!resultsData) { + throw 'resultsData was null or undefined'; + } + let data = dataPath.split('.').reduce((d: any, p: any) => { + if (!d) { + return null; + } + return d[p]; + }, resultsData.data); + if (!data) { + const errors: any[] = resultsData.errors; + if (errors && errors.length !== 0) { + throw errors[0]; + } + throw 'Your data path did not exist! dataPath: ' + dataPath; + } + if (resultsData.errors) { + // There can still be errors even if there is data + console.log('Got GraphQL errors:'); + console.log(resultsData.errors); + } + const docs: any[] = []; + let pushDoc = (originalDoc: object) => { + docs.push(flatten(originalDoc)); + }; + if (Array.isArray(data)) { + for (const element of data) { + pushDoc(element); + } + } else { + pushDoc(data); + } + return docs; + } + private static getDataPathArray(dataPathString: string): string[] { + const dataPathArray: string[] = []; + for (const dataPath of dataPathString.split(',')) { + const trimmed = dataPath.trim(); + if (trimmed) { + dataPathArray.push(trimmed); + } + } + if (!dataPathArray) { + throw 'data path is empty!'; + } + return dataPathArray; + } + + async query(options: DataQueryRequest): Promise { + return Promise.all( + options.targets.map((target) => { + return this.createQuery(defaults(target, defaultQuery), options.range, options.scopedVars); + }) + ).then((results: any) => { + const dataFrameArray: DataFrame[] = []; + for (let res of results) { + const dataPathArray: string[] = DataSource.getDataPathArray(res.query.dataPath); + const { timePath, timeFormat, groupBy, aliasBy } = res.query; + const split = groupBy.split(','); + const groupByList: string[] = []; + for (const element of split) { + const trimmed = element.trim(); + if (trimmed) { + groupByList.push(trimmed); + } + } + for (const dataPath of dataPathArray) { + const docs: any[] = DataSource.getDocs(res.results.data, dataPath); + + const dataFrameMap = new Map(); + for (const doc of docs) { + if (timePath in doc) { + doc[timePath] = dateTime(doc[timePath], timeFormat); + } + const identifiers: string[] = []; + for (const groupByElement of groupByList) { + identifiers.push(doc[groupByElement]); + } + const identifiersString = identifiers.toString(); + let dataFrame = dataFrameMap.get(identifiersString); + if (!dataFrame) { + // we haven't initialized the dataFrame for this specific identifier that we group by yet + dataFrame = new MutableDataFrame({ fields: [] }); + const generalReplaceObject: any = {}; + for (const fieldName in doc) { + generalReplaceObject['field_' + fieldName] = doc[fieldName]; + } + for (const fieldName in doc) { + let t: FieldType = FieldType.string; + if (fieldName === timePath || isRFC3339_ISO6801(String(doc[fieldName]))) { + t = FieldType.time; + } else if (_.isNumber(doc[fieldName])) { + t = FieldType.number; + } + let title; + if (identifiers.length !== 0) { + // if we have any identifiers + title = identifiersString + '_' + fieldName; + } else { + title = fieldName; + } + if (aliasBy) { + title = aliasBy; + const replaceObject = { ...generalReplaceObject }; + replaceObject['fieldName'] = fieldName; + for (const replaceKey in replaceObject) { + const replaceValue = replaceObject[replaceKey]; + const regex = new RegExp('\\$' + replaceKey, 'g'); + title = title.replace(regex, replaceValue); + } + title = getTemplateSrv().replace(title, options.scopedVars); + } + dataFrame.addField({ + name: fieldName, + type: t, + config: { displayName: title }, + }).parse = (v: any) => { + return v || ''; + }; + } + dataFrameMap.set(identifiersString, dataFrame); + } + + dataFrame.add(doc); + } + for (const dataFrame of dataFrameMap.values()) { + dataFrameArray.push(dataFrame); + } + } + } + return { data: dataFrameArray }; + }); + } + annotationQuery(options: AnnotationQueryRequest): Promise { + const query = defaults(options.annotation, defaultQuery); + return Promise.all([this.createQuery(query, options.range)]).then((results: any) => { + const r: AnnotationEvent[] = []; + for (const res of results) { + const { timePath, endTimePath, timeFormat } = res.query; + const dataPathArray: string[] = DataSource.getDataPathArray(res.query.dataPath); + for (const dataPath of dataPathArray) { + const docs: any[] = DataSource.getDocs(res.results.data, dataPath); + for (const doc of docs) { + const annotation: AnnotationEvent = {}; + if (timePath in doc) { + annotation.time = dateTime(doc[timePath], timeFormat).valueOf(); + } + if (endTimePath in doc) { + annotation.isRegion = true; + annotation.timeEnd = dateTime(doc[endTimePath], timeFormat).valueOf(); + } + let title = query.annotationTitle; + let text = query.annotationText; + let tags = query.annotationTags; + for (const fieldName in doc) { + const fieldValue = doc[fieldName]; + const replaceKey = 'field_' + fieldName; + const regex = new RegExp('\\$' + replaceKey, 'g'); + title = title.replace(regex, fieldValue); + text = text.replace(regex, fieldValue); + tags = tags.replace(regex, fieldValue); + } + + annotation.title = title; + annotation.text = text; + const tagsList: string[] = []; + for (const element of tags.split(',')) { + const trimmed = element.trim(); + if (trimmed) { + tagsList.push(trimmed); + } + } + annotation.tags = tagsList; + r.push(annotation); + } + } + } + return r; + }); + } + + testDatasource() { + const q = `{ + __schema{ + queryType{name} + } + }`; + return this.postQuery(defaultQuery, q).then( + (res: any) => { + if (res.errors) { + console.log(res.errors); + return { + status: 'error', + message: 'GraphQL Error: ' + res.errors[0].message, + }; + } + return { + status: 'success', + message: 'Success', + }; + }, + (err: any) => { + console.log(err); + return { + status: 'error', + message: 'HTTP Response ' + err.status + ': ' + err.statusText, + }; + } + ); + } + + async metricFindQuery(query: MyVariableQuery, options?: any) { + const metricFindValues: MetricFindValue[] = []; + + query = defaults(query, defaultQuery); + + let payload = query.queryText; + payload = getTemplateSrv().replace(payload, { ...this.getVariables }); + + const response = await this.postQuery(query, payload); + + const docs: any[] = DataSource.getDocs(response.results.data, query.dataPath); + + for (const doc of docs) { + if ('__text' in doc && '__value' in doc) { + metricFindValues.push({ text: doc['__text'], value: doc['__value'] }); + } else { + for (const fieldName in doc) { + metricFindValues.push({ text: doc[fieldName] }); + } + } + } + + return metricFindValues; + } + + getVariables() { + const variables: { [id: string]: TextValuePair } = {}; + Object.values(getTemplateSrv().getVariables()).forEach((variable) => { + if (!supportedVariableTypes.includes(variable.type)) { + console.warn(`Variable of type "${variable.type}" is not supported`); + + return; + } + + const supportedVariable = variable as MultiValueVariable; + + let variableValue = supportedVariable.current.value; + if (variableValue === '$__all' || isEqual(variableValue, ['$__all'])) { + if (supportedVariable.allValue === null || supportedVariable.allValue === '') { + variableValue = supportedVariable.options.slice(1).map((textValuePair) => textValuePair.value); + } else { + variableValue = supportedVariable.allValue; + } + } + + variables[supportedVariable.id] = { + text: supportedVariable.current.text, + value: variableValue, + }; + }); + + return variables; + } +} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts new file mode 100644 index 0000000000000..30b4688c4a618 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts @@ -0,0 +1,364 @@ +import _ from 'lodash'; +import { isEqual } from 'lodash'; +import defaults from 'lodash/defaults'; + +import { + AnnotationEvent, + AnnotationQueryRequest, + DataQueryRequest, + DataQueryResponse, + MetricFindValue, + DataSourceInstanceSettings, + ScopedVars, + TimeRange, +} from '@grafana/data'; +import { dateTime, MutableDataFrame, FieldType, DataFrame } from '@grafana/data'; +import { getTemplateSrv, DataSourceWithBackend } from '@grafana/runtime'; +import { BackendSrv, getBackendSrv } from 'app/core/services/backend_srv'; + +import { BackendSrvRequest } from '../../../../../packages/grafana-runtime/src/services/backendSrv'; + +import { + MyQuery, + MyDataSourceOptions, + defaultQuery, + MyVariableQuery, + MultiValueVariable, + TextValuePair, +} from './types'; +import { flatten, isRFC3339_ISO6801 } from './util'; + +const supportedVariableTypes = ['constant', 'custom', 'query', 'textbox']; + +export class FN_DataSource extends DataSourceWithBackend { + basicAuth: string | undefined; + withCredentials: boolean | undefined; + url: string | undefined; + backendSrv: BackendSrv; + + constructor(instanceSettings: DataSourceInstanceSettings) { + super(instanceSettings); + this.basicAuth = instanceSettings.basicAuth; + this.withCredentials = instanceSettings.withCredentials; + // const url = instanceSettings.jsonData["connection.url"] + // const url = "http://localhost:8081/api/query" + this.url = instanceSettings.url; + + this.backendSrv = getBackendSrv(); + } + + private request(data: string) { + const options: BackendSrvRequest = { + url: this.url as string, + method: 'POST', + data: { + query: data, + }, + }; + + if (this.basicAuth || this.withCredentials) { + options.withCredentials = true; + } + + if (this.basicAuth) { + options.headers = { + Authorization: this.basicAuth, + }; + } + + return this.backendSrv.datasourceRequest(options); + } + + private postQuery(query: Partial, payload: string) { + return this.request(payload) + .then((results: any) => { + return { query, results }; + }) + .catch((err: any) => { + if (err.data && err.data.error) { + throw { + message: 'GraphQL error: ' + err.data.error.reason, + error: err.data.error, + }; + } + + throw err; + }); + } + + private createQuery(query: MyQuery, range: TimeRange | undefined, scopedVars: ScopedVars | undefined = undefined) { + let payload = getTemplateSrv().replace(query.queryText, { + ...scopedVars, + timeFrom: { text: 'from', value: range?.from.valueOf() }, + timeTo: { text: 'to', value: range?.to.valueOf() }, + }); + + //console.log(payload); + return this.postQuery(query, payload); + } + private static getDocs(resultsData: any, dataPath: string): any[] { + if (!resultsData) { + throw 'resultsData was null or undefined'; + } + let data = dataPath.split('.').reduce((d: any, p: any) => { + if (!d) { + return null; + } + return d[p]; + }, resultsData.data); + if (!data) { + const errors: any[] = resultsData.errors; + if (errors && errors.length !== 0) { + throw errors[0]; + } + throw 'Your data path did not exist! dataPath: ' + dataPath; + } + if (resultsData.errors) { + // There can still be errors even if there is data + console.log('Got GraphQL errors:'); + console.log(resultsData.errors); + } + const docs: any[] = []; + let pushDoc = (originalDoc: object) => { + docs.push(flatten(originalDoc)); + }; + if (Array.isArray(data)) { + for (const element of data) { + pushDoc(element); + } + } else { + pushDoc(data); + } + return docs; + } + private static getDataPathArray(dataPathString: string): string[] { + const dataPathArray: string[] = []; + for (const dataPath of dataPathString.split(',')) { + const trimmed = dataPath.trim(); + if (trimmed) { + dataPathArray.push(trimmed); + } + } + if (!dataPathArray) { + throw 'data path is empty!'; + } + return dataPathArray; + } + + async query(options: DataQueryRequest): Promise { + return Promise.all( + options.targets.map((target) => { + return this.createQuery(defaults(target, defaultQuery), options.range, options.scopedVars); + }) + ).then((results: any) => { + const dataFrameArray: DataFrame[] = []; + for (let res of results) { + const dataPathArray: string[] = FN_DataSource.getDataPathArray(res.query.dataPath); + const { timePath, timeFormat, groupBy, aliasBy } = res.query; + const split = groupBy.split(','); + const groupByList: string[] = []; + for (const element of split) { + const trimmed = element.trim(); + if (trimmed) { + groupByList.push(trimmed); + } + } + for (const dataPath of dataPathArray) { + const docs: any[] = FN_DataSource.getDocs(res.results.data, dataPath); + + const dataFrameMap = new Map(); + for (const doc of docs) { + if (timePath in doc) { + doc[timePath] = dateTime(doc[timePath], timeFormat); + } + const identifiers: string[] = []; + for (const groupByElement of groupByList) { + identifiers.push(doc[groupByElement]); + } + const identifiersString = identifiers.toString(); + let dataFrame = dataFrameMap.get(identifiersString); + if (!dataFrame) { + // we haven't initialized the dataFrame for this specific identifier that we group by yet + dataFrame = new MutableDataFrame({ fields: [] }); + const generalReplaceObject: any = {}; + for (const fieldName in doc) { + generalReplaceObject['field_' + fieldName] = doc[fieldName]; + } + for (const fieldName in doc) { + let t: FieldType = FieldType.string; + if (fieldName === timePath || isRFC3339_ISO6801(String(doc[fieldName]))) { + t = FieldType.time; + } else if (_.isNumber(doc[fieldName])) { + t = FieldType.number; + } + let title; + if (identifiers.length !== 0) { + // if we have any identifiers + title = identifiersString + '_' + fieldName; + } else { + title = fieldName; + } + if (aliasBy) { + title = aliasBy; + const replaceObject = { ...generalReplaceObject }; + replaceObject['fieldName'] = fieldName; + for (const replaceKey in replaceObject) { + const replaceValue = replaceObject[replaceKey]; + const regex = new RegExp('\\$' + replaceKey, 'g'); + title = title.replace(regex, replaceValue); + } + title = getTemplateSrv().replace(title, options.scopedVars); + } + dataFrame.addField({ + name: fieldName, + type: t, + config: { displayName: title }, + }).parse = (v: any) => { + return v || ''; + }; + } + dataFrameMap.set(identifiersString, dataFrame); + } + + dataFrame.add(doc); + } + for (const dataFrame of dataFrameMap.values()) { + dataFrameArray.push(dataFrame); + } + } + } + return { data: dataFrameArray }; + }); + } + annotationQuery(options: AnnotationQueryRequest): Promise { + const query = defaults(options.annotation, defaultQuery); + return Promise.all([this.createQuery(query, options.range)]).then((results: any) => { + const r: AnnotationEvent[] = []; + for (const res of results) { + const { timePath, endTimePath, timeFormat } = res.query; + const dataPathArray: string[] = FN_DataSource.getDataPathArray(res.query.dataPath); + for (const dataPath of dataPathArray) { + const docs: any[] = FN_DataSource.getDocs(res.results.data, dataPath); + for (const doc of docs) { + const annotation: AnnotationEvent = {}; + if (timePath in doc) { + annotation.time = dateTime(doc[timePath], timeFormat).valueOf(); + } + if (endTimePath in doc) { + annotation.isRegion = true; + annotation.timeEnd = dateTime(doc[endTimePath], timeFormat).valueOf(); + } + let title = query.annotationTitle; + let text = query.annotationText; + let tags = query.annotationTags; + for (const fieldName in doc) { + const fieldValue = doc[fieldName]; + const replaceKey = 'field_' + fieldName; + const regex = new RegExp('\\$' + replaceKey, 'g'); + title = title.replace(regex, fieldValue); + text = text.replace(regex, fieldValue); + tags = tags.replace(regex, fieldValue); + } + + annotation.title = title; + annotation.text = text; + const tagsList: string[] = []; + for (const element of tags.split(',')) { + const trimmed = element.trim(); + if (trimmed) { + tagsList.push(trimmed); + } + } + annotation.tags = tagsList; + r.push(annotation); + } + } + } + return r; + }); + } + + testDatasource() { + const q = `{ + __schema{ + queryType{name} + } + }`; + return this.postQuery(defaultQuery, q).then( + (res: any) => { + if (res.errors) { + console.log(res.errors); + return { + status: 'error', + message: 'GraphQL Error: ' + res.errors[0].message, + }; + } + return { + status: 'success', + message: 'Success', + }; + }, + (err: any) => { + console.log(err); + return { + status: 'error', + message: 'HTTP Response ' + err.status + ': ' + err.statusText, + }; + } + ); + } + + async metricFindQuery(query: MyVariableQuery, options?: any) { + const metricFindValues: MetricFindValue[] = []; + + query = defaults(query, defaultQuery); + + let payload = query.queryText; + payload = getTemplateSrv().replace(payload, { ...this.getVariables }); + + const response = await this.postQuery(query, payload); + + const docs: any[] = FN_DataSource.getDocs(response.results.data, query.dataPath); + + for (const doc of docs) { + if ('__text' in doc && '__value' in doc) { + metricFindValues.push({ text: doc['__text'], value: doc['__value'] }); + } else { + for (const fieldName in doc) { + metricFindValues.push({ text: doc[fieldName] }); + } + } + } + + return metricFindValues; + } + + getVariables() { + const variables: { [id: string]: TextValuePair } = {}; + Object.values(getTemplateSrv().getVariables()).forEach((variable) => { + if (!supportedVariableTypes.includes(variable.type)) { + console.warn(`Variable of type "${variable.type}" is not supported`); + + return; + } + + const supportedVariable = variable as MultiValueVariable; + + let variableValue = supportedVariable.current.value; + if (variableValue === '$__all' || isEqual(variableValue, ['$__all'])) { + if (supportedVariable.allValue === null || supportedVariable.allValue === '') { + variableValue = supportedVariable.options.slice(1).map((textValuePair) => textValuePair.value); + } else { + variableValue = supportedVariable.allValue; + } + } + + variables[supportedVariable.id] = { + text: supportedVariable.current.text, + value: variableValue, + }; + }); + + return variables; + } +} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/GraphQLAnnotationsQueryCtrl.tsx b/public/app/plugins/datasource/fifemon-graphql-datasource/GraphQLAnnotationsQueryCtrl.tsx new file mode 100644 index 0000000000000..cfc76866f2fe2 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/GraphQLAnnotationsQueryCtrl.tsx @@ -0,0 +1,5 @@ +export class GraphQLAnnotationsQueryCtrl { + static templateUrl = 'partials/annotations.editor.html'; + annotation: any; + constructor() {} +} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/QueryEditor.tsx b/public/app/plugins/datasource/fifemon-graphql-datasource/QueryEditor.tsx new file mode 100644 index 0000000000000..4ed8a4f4e7c2a --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/QueryEditor.tsx @@ -0,0 +1,110 @@ +import defaults from 'lodash/defaults'; + +import React, { PureComponent, ChangeEvent } from 'react'; +import { QueryEditorProps } from '@grafana/data'; +import { LegacyForms, QueryField, Icon } from '@grafana/ui'; +import { FN_DataSource } from './FN_DataSource'; +import { MyQuery, MyDataSourceOptions, defaultQuery } from './types'; + +type Props = QueryEditorProps; + +interface State {} + +export class QueryEditor extends PureComponent { + onComponentDidMount() {} + + onChangeQuery = (value: string, override?: boolean) => { + const { onChange, query } = this.props; + if (onChange) { + onChange({ ...query, queryText: value }); + } + }; + + onDataPathTextChange = (event: ChangeEvent) => { + const { onChange, query } = this.props; + onChange({ ...query, dataPath: event.target.value }); + }; + onTimePathTextChange = (event: ChangeEvent) => { + const { onChange, query } = this.props; + onChange({ ...query, timePath: event.target.value }); + }; + onTimeFormatTextChange = (event: ChangeEvent) => { + const { onChange, query } = this.props; + onChange({ ...query, timeFormat: event.target.value }); + }; + onGroupByTextChange = (event: ChangeEvent) => { + const { onChange, query } = this.props; + onChange({ ...query, groupBy: event.target.value }); + }; + + onAliasByTextChange = (event: ChangeEvent) => { + const { onChange, query } = this.props; + onChange({ ...query, aliasBy: event.target.value }); + }; + + render() { + const query = defaults(this.props.query, defaultQuery); + const { queryText, dataPath, timePath, timeFormat, groupBy, aliasBy } = query; + + return ( + <> + +
+ +
+
+ +
+
+
+ +
+
+ +
+ + ); + } +} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/VariableQueryEditor.tsx b/public/app/plugins/datasource/fifemon-graphql-datasource/VariableQueryEditor.tsx new file mode 100644 index 0000000000000..9cde921c74813 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/VariableQueryEditor.tsx @@ -0,0 +1,47 @@ +import { QueryField } from '@grafana/ui'; +import React, { useState } from 'react'; +import { MyQuery } from './types'; + +interface VariableQueryProps { + query: MyQuery; + onChange: (query: MyQuery, definition: string) => void; +} + +export const VariableQueryEditor: React.FC = ({ onChange, query }) => { + const [state, setState] = useState(query); + + const saveQuery = () => { + onChange(state, `${state.queryText} (${state.dataPath})`); + }; + + const onChangeQuery = (value: string, override?: boolean) => + setState({ + ...state, + queryText: value, + }); + + const handleChange = (event: React.FormEvent) => + setState({ + ...state, + [event.currentTarget.name]: event.currentTarget.value, + }); + + return ( + <> +
+ Data Path + +
+
+ Query + +
+ + ); +}; diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/img/README b/public/app/plugins/datasource/fifemon-graphql-datasource/img/README new file mode 100644 index 0000000000000..0b1525180d962 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/img/README @@ -0,0 +1,4 @@ +GraphQL Logo Copyright © 2015-2018, Facebook, Inc. Copyright © 2019-present, GraphQL Foundation +Obtained from: https://github.com/graphql/graphql-spec/blob/master/resources/GraphQL%20Logo.svg +Used under the terms of the Open Web Foundation Final Specification Agreement (OWFa 1.0) per +https://github.com/graphql/graphql-spec/blob/master/spec/GraphQL.md \ No newline at end of file diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/img/db_arrivals.png b/public/app/plugins/datasource/fifemon-graphql-datasource/img/db_arrivals.png new file mode 100644 index 0000000000000000000000000000000000000000..5f9e3ce77d6c36f82dbaeb18f7b7bac783470839 GIT binary patch literal 104030 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

Ng{sL+^{Y4MyBBWz?dLnQ-BGT2wr}2#ZBIq0 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 literal 0 HcmV?d00001 diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/img/github_security_advisories.png b/public/app/plugins/datasource/fifemon-graphql-datasource/img/github_security_advisories.png new file mode 100644 index 0000000000000000000000000000000000000000..71300cfb7c371c50aaa8e916815e0c04f2d1880b GIT binary patch literal 137186 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�F3dg+28uIJv4DF0 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

%M?;geSO?bRIkyUr3O%dPZJr)3>dL82v86 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 + + + diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/module.test.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/module.test.ts new file mode 100644 index 0000000000000..5e199ed0fa738 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/module.test.ts @@ -0,0 +1,5 @@ +describe('placeholder test', () => { + it('should return true', () => { + expect(true).toBeTruthy(); + }); +}); diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/module.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/module.ts new file mode 100644 index 0000000000000..9da530c68e2cd --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/module.ts @@ -0,0 +1,13 @@ +import { DataSourcePlugin } from '@grafana/data'; +import { FN_DataSource } from './FN_DataSource'; +import { ConfigEditor } from './ConfigEditor'; +import { QueryEditor } from './QueryEditor'; +import { MyQuery, MyDataSourceOptions } from './types'; +import { GraphQLAnnotationsQueryCtrl } from './GraphQLAnnotationsQueryCtrl'; +import { VariableQueryEditor } from './VariableQueryEditor'; + +export const plugin = new DataSourcePlugin(FN_DataSource) + .setConfigEditor(ConfigEditor) + .setAnnotationQueryCtrl(GraphQLAnnotationsQueryCtrl) + .setQueryEditor(QueryEditor) + .setVariableQueryEditor(VariableQueryEditor); diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/partials/annotations.editor.html b/public/app/plugins/datasource/fifemon-graphql-datasource/partials/annotations.editor.html new file mode 100644 index 0000000000000..99824c44211fe --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/partials/annotations.editor.html @@ -0,0 +1,74 @@ + + + + + + +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/plugin.json b/public/app/plugins/datasource/fifemon-graphql-datasource/plugin.json new file mode 100644 index 0000000000000..cf5a57a9fa2e3 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/plugin.json @@ -0,0 +1,36 @@ +{ + "type": "datasource", + "name": "GraphQL Data Source", + "id": "fifemon-graphql-datasource", + "metrics": true, + "annotations": true, + + "info": { + "description": "GraphQL Data Source", + "author": { + "name": "Kevin Retzke" + }, + "keywords": ["GraphQL"], + "logos": { + "small": "img/logo.svg", + "large": "img/logo.svg" + }, + "links": [ + { "name": "Website", "url": "https://github.com/fifemon/graphql-datasource" }, + { "name": "License", "url": "https://github.com/fifemon/graphql-datasource/blob/master/LICENSE" } + ], + "screenshots": [ + { "name": "DeutscheBahn Arrivals", "path": "img/db_arrivals.png"}, + { "name": "DeutscheBahn Arrivals Annotations", "path": "img/db_arrivals_annotations.png"}, + { "name": "GitHub Security Advisories", "path": "img/github_security_advisories.png"} + ], + "version": "%VERSION%", + "updated": "%TODAY%" + }, + + "dependencies": { + "grafanaVersion": "7.x.x", + "grafanaDependency": ">=7.0.0", + "plugins": [] + } +} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/types.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/types.ts new file mode 100644 index 0000000000000..4b4819512a3a2 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/types.ts @@ -0,0 +1,58 @@ +import { DataQuery, DataSourceJsonData, VariableModel } from '@grafana/data'; + +export interface MyQuery extends DataQuery { + queryText: string; + dataPath: string; + timePath: string; + endTimePath: string | null; + timeFormat: string | null; + groupBy: string; + aliasBy: string; + annotationTitle: string; + annotationText: string; + annotationTags: string; + constant: number; +} + +export const defaultQuery: Partial = { + queryText: `query { + data:submissions(user:"$user"){ + Time:submitTime + idle running completed + } +}`, + dataPath: 'data', + timePath: 'Time', + endTimePath: 'endTime', + timeFormat: null, + groupBy: '', // `identifier` + aliasBy: '', // 'Server [[tag_identifier]]` + annotationTitle: '', + annotationText: '', + annotationTags: '', + constant: 6.5, +}; + +/** + * These are options configured for each DataSource instance + */ +export interface MyDataSourceOptions extends DataSourceJsonData { + apiKey?: string; +} + +export interface MyVariableQuery extends DataQuery { + dataPath: string; + queryText: string; +} + +export interface TextValuePair { + text: string; + value: any; +} + +export interface MultiValueVariable extends VariableModel { + allValue: string | null; + id: string; + current: TextValuePair; + options: TextValuePair[]; +} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/util.test.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/util.test.ts new file mode 100644 index 0000000000000..c91386f359147 --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/util.test.ts @@ -0,0 +1,51 @@ +import { flatten, isRFC3339_ISO6801 } from './util'; + +test('flatten function test', () => { + let obj = { + string: 'hello', + number: 123, + float: 123.4, + null: null, + undefined: undefined, + array: [1, 2, 3], + nested: { + string: 'hello', + number: 123, + float: 123.4, + null: null, + undefined: undefined, + }, + }; + + let flattenObj = { + string: 'hello', + number: 123, + float: 123.4, + null: null, + undefined: undefined, + 'array.0': 1, + 'array.1': 2, + 'array.2': 3, + 'nested.string': 'hello', + 'nested.number': 123, + 'nested.float': 123.4, + 'nested.null': null, + 'nested.undefined': undefined, + }; + + expect(flatten(obj)).toEqual(flattenObj); +}); + +test('RFC3339 and ISO8601 valid string test', () => { + expect(isRFC3339_ISO6801('I am not a date but a string')).toBe(false); + expect(isRFC3339_ISO6801('1234')).toBe(false); + expect(isRFC3339_ISO6801(String(8))).toBe(false); + expect(isRFC3339_ISO6801(String(null))).toBe(false); + expect(isRFC3339_ISO6801('2020-06-01T00:00:00.000Z')).toBe(true); + expect(isRFC3339_ISO6801('2020-06-01T00:00:00Z')).toBe(true); + expect(isRFC3339_ISO6801(String(true))).toBe(false); + expect(isRFC3339_ISO6801(String(0))).toBe(false); + expect(isRFC3339_ISO6801(String(Number.MAX_SAFE_INTEGER))).toBe(false); + expect(isRFC3339_ISO6801(String(0.111111))).toBe(false); + expect(isRFC3339_ISO6801(String(1603810963000))).toBe(false); +}); diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/util.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/util.ts new file mode 100644 index 0000000000000..e3f586668514c --- /dev/null +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/util.ts @@ -0,0 +1,23 @@ +import { dateTime, ISO_8601 } from '@grafana/data'; + +export function flatten>(object: T, path: string | null = null, separator = '.'): T { + return Object.keys(object).reduce((acc: T, key: string): T => { + const isObject = typeof object[key] === 'object' && object[key] != null; + const newPath = [path, key].filter(Boolean).join(separator); + return isObject ? { ...acc, ...flatten(object[key], newPath, separator) } : { ...acc, [newPath]: object[key] }; + }, {} as T); +} + +export function isRFC3339_ISO6801(str: string): boolean { + let date = dateTime(str, ISO_8601); + if (date.isValid()) { + let iso = date.toISOString(); + if (iso === str) { + return true; + } else { + // some RFC3339 dates don't include fractions of a second to same resolution, but still valid. + return iso.substring(0, 19) === str.substring(0, 19); + } + } + return false; +} From ce49033a7d0552bd098bdc49a7df191234104346 Mon Sep 17 00:00:00 2001 From: Kasia <24753130+ziomecka@users.noreply.github.com> Date: Fri, 20 Jan 2023 09:07:21 +0100 Subject: [PATCH 026/101] 7911 Allow loading unsigned graphql plugin (#49) Co-authored-by: Katarzyna Ziomek-Zdanowicz --- conf/defaults.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/defaults.ini b/conf/defaults.ini index 72c021b7e794a..87e32001a0199 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1707,7 +1707,7 @@ disable_sanitize_html = false enable_alpha = false app_tls_skip_verify_insecure = false # Enter a comma-separated list of plugin identifiers to identify plugins to load even if they are unsigned. Plugins with modified signatures are never loaded. -allow_loading_unsigned_plugins = +allow_loading_unsigned_plugins = fifemon-graphql-datasource # Enable or disable installing / uninstalling / updating plugins directly from within Grafana. plugin_admin_enabled = true plugin_admin_external_manage_enabled = false From f83d7c1c34c260c25ee38984a54190183b3142fc Mon Sep 17 00:00:00 2001 From: Kasia <24753130+ziomecka@users.noreply.github.com> Date: Fri, 20 Jan 2023 14:43:09 +0100 Subject: [PATCH 027/101] 7911 Modify url in graphql datasource plugin (#50) Co-authored-by: Katarzyna Ziomek-Zdanowicz --- .../datasource/fifemon-graphql-datasource/FN_DataSource.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts index 30b4688c4a618..0b8a9c3aa1d8b 100644 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts +++ b/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts @@ -40,9 +40,11 @@ export class FN_DataSource extends DataSourceWithBackend Date: Thu, 2 Feb 2023 13:56:08 +0100 Subject: [PATCH 028/101] Minor grafadruid fixes (#51) --- pkg/tsdb/druid/druid.go | 8 +++----- pkg/tsdb/druid/result/common.go | 3 ++- pkg/tsdb/druid/result/timeseries.go | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pkg/tsdb/druid/druid.go b/pkg/tsdb/druid/druid.go index a19c3f3a4a6c4..91a50ca7a386c 100644 --- a/pkg/tsdb/druid/druid.go +++ b/pkg/tsdb/druid/druid.go @@ -451,11 +451,9 @@ func (ds *Service) prepareQuery(qry []byte, s *druidInstanceSettings) (druidquer func (ds *Service) prepareQueryContext(parameters []interface{}) map[string]interface{} { ctx := make(map[string]interface{}) - if parameters != nil { - for _, parameter := range parameters { - p := parameter.(map[string]interface{}) - ctx[p["name"].(string)] = p["value"] - } + for _, parameter := range parameters { + p := parameter.(map[string]interface{}) + ctx[p["name"].(string)] = p["value"] } return ctx } diff --git a/pkg/tsdb/druid/result/common.go b/pkg/tsdb/druid/result/common.go index 7926a59ac07b8..5d15a866c8d6b 100644 --- a/pkg/tsdb/druid/result/common.go +++ b/pkg/tsdb/druid/result/common.go @@ -1,6 +1,7 @@ package result import ( + "fmt" "time" "github.com/grafana/grafana-plugin-sdk-go/backend/log" @@ -75,7 +76,7 @@ func toTypedResults(raw []interface{}) interface{} { return results default: // TODO better error handling - log.DefaultLogger.Debug("Unsupported value %T", raw[0]) + log.DefaultLogger.Debug(fmt.Sprintf("Unsupported type %T", raw[0])) return nil } } diff --git a/pkg/tsdb/druid/result/timeseries.go b/pkg/tsdb/druid/result/timeseries.go index 47e497522e549..ec9e20e64fa52 100644 --- a/pkg/tsdb/druid/result/timeseries.go +++ b/pkg/tsdb/druid/result/timeseries.go @@ -47,7 +47,7 @@ type TimeseriesRecord struct { } // Columns returns list of columns for given record. -// The first column will always be "timestamp" followed by other columns sorter +// The first column will always be "timestamp" followed by other columns sorted // alphabetically. func (t *TimeseriesRecord) Columns() []string { columns := make([]string, len(t.Result)+1) From ebee8486575ad1fde88ff954d8c49c3cd7bbeeea Mon Sep 17 00:00:00 2001 From: Jakub Michalak Date: Fri, 3 Feb 2023 12:44:15 +0100 Subject: [PATCH 029/101] Support Druid GroupBy queries (#52) --- pkg/tsdb/druid/druid.go | 7 ++- pkg/tsdb/druid/result/groupby.go | 74 +++++++++++++++++++++++++++ pkg/tsdb/druid/result/groupby_test.go | 60 ++++++++++++++++++++++ pkg/tsdb/druid/result/topn.go | 2 +- 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 pkg/tsdb/druid/result/groupby.go create mode 100644 pkg/tsdb/druid/result/groupby_test.go diff --git a/pkg/tsdb/druid/druid.go b/pkg/tsdb/druid/druid.go index 91a50ca7a386c..27e00f3bdc005 100644 --- a/pkg/tsdb/druid/druid.go +++ b/pkg/tsdb/druid/druid.go @@ -486,7 +486,12 @@ func (ds *Service) executeQuery( } resultFramer = &r case "groupBy": - return nil, errors.New("not implemented") + var r result.GroupByResult + _, err := s.client.Query().Execute(q, &r, headers) + if err != nil { + return nil, fmt.Errorf("Query error: %w", err) + } + resultFramer = &r case "scan": q.(*druidquery.Scan).SetResultFormat("compactedList") return nil, errors.New("not implemented") diff --git a/pkg/tsdb/druid/result/groupby.go b/pkg/tsdb/druid/result/groupby.go new file mode 100644 index 0000000000000..e3cb2a49b9472 --- /dev/null +++ b/pkg/tsdb/druid/result/groupby.go @@ -0,0 +1,74 @@ +package result + +import ( + "sort" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/data" +) + +type GroupByResult []GroupByRecord + +// Frame returns data formatted as Grafana Frame. +func (t *GroupByResult) Frame() *data.Frame { + columns := t.Columns() + fields := make([]*data.Field, len(columns)) + for i, column := range columns { + labels := data.Labels{} + fields[i] = data.NewField(column, labels, t.Values(column)) + } + return data.NewFrame("", fields...) +} + +// Columns returns list of columns. It calls `Columns()` on first record. If +// no records are available it returns nil. +func (t *GroupByResult) Columns() []string { + for _, r := range *t { + return r.Columns() + } + return nil +} + +// Values returns all values for given column. +func (t *GroupByResult) Values(column string) interface{} { + if len(*t) == 0 { + return nil + } + results := make([]interface{}, len(*t)) + for i, r := range *t { + results[i] = r.Value(column) + } + return toTypedResults(results) +} + +type GroupByRecord struct { + Timestamp time.Time `json:"timestamp"` + Event map[string]interface{} `json:"event"` +} + +// Columns returns list of columns for given record. +// The first column will always be "timestamp" followed by other columns sorted +// alphabetically. +func (t *GroupByRecord) Columns() []string { + columns := make([]string, len(t.Event)+1) + columns[0] = timestampColumn + i := 1 + for c := range t.Event { + columns[i] = c + i++ + } + sort.Strings(columns[1:]) + return columns +} + +// Value returns value for given column. +func (t *GroupByRecord) Value(column string) interface{} { + if column == timestampColumn { + return t.Timestamp + } + v, ok := t.Event[column] + if !ok { + return nil + } + return v +} diff --git a/pkg/tsdb/druid/result/groupby_test.go b/pkg/tsdb/druid/result/groupby_test.go new file mode 100644 index 0000000000000..80cc4cb335b67 --- /dev/null +++ b/pkg/tsdb/druid/result/groupby_test.go @@ -0,0 +1,60 @@ +package result + +import ( + "encoding/json" + "testing" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/data" + "github.com/stretchr/testify/assert" +) + +func TestGroupByResultUnmarshal(t *testing.T) { + input := []byte(`[ + { + "timestamp": "2022-10-14T08:08:10.000Z", + "event": { + "dog_count": 47, + "dog_rate": 2.083, + "dog_name": "foo" + } + }, + { + "timestamp": "2022-10-14T08:08:11.000Z", + "event": { + "dog_count": 75, + "dog_rate": 3.846, + "dog_name": "bar" + } + } + ]`) + + var res GroupByResult + err := json.Unmarshal(input, &res) + assert.Nil(t, err, "Failed to unmarshal response") + assert.Equal(t, len(res), 2, "Wrong number of unmarshalled results") + frame := res.Frame() + assert.Equal(t, len(frame.Fields), 4, "Wrong number of framed fields") + + assert.Equal(t, frame.Fields[0].Name, "timestamp") + assert.Equal(t, frame.Fields[0].Type(), data.FieldTypeTime) + assert.Equal(t, frame.Fields[0].Len(), 2) + assert.Equal(t, frame.Fields[0].At(0), time.Time(time.Date(2022, time.October, 14, 8, 8, 10, 0, time.UTC))) + assert.Equal(t, frame.Fields[0].At(1), time.Time(time.Date(2022, time.October, 14, 8, 8, 11, 0, time.UTC))) + + assert.Equal(t, frame.Fields[1].Name, "dog_count") + assert.Equal(t, frame.Fields[1].Type(), data.FieldTypeFloat64) + assert.Equal(t, frame.Fields[1].At(0), float64(47)) + assert.Equal(t, frame.Fields[1].At(1), float64(75)) + + assert.Equal(t, frame.Fields[2].Name, "dog_name") + assert.Equal(t, frame.Fields[2].Type(), data.FieldTypeString) + assert.Equal(t, frame.Fields[2].At(0), "foo") + assert.Equal(t, frame.Fields[2].At(1), "bar") + + assert.Equal(t, frame.Fields[3].Name, "dog_rate") + assert.Equal(t, frame.Fields[3].Type(), data.FieldTypeFloat64) + assert.Equal(t, frame.Fields[3].At(0), float64(2.083)) + assert.Equal(t, frame.Fields[3].At(1), float64(3.846)) + +} diff --git a/pkg/tsdb/druid/result/topn.go b/pkg/tsdb/druid/result/topn.go index 035dc23b4f67e..ba64fa7dc508b 100644 --- a/pkg/tsdb/druid/result/topn.go +++ b/pkg/tsdb/druid/result/topn.go @@ -46,7 +46,7 @@ type TopNRecord struct { // Columns returns list of columns for given record. // It assumes that every map from Result has the same columns, so it gets // the list from first item. -// The first column will always be "timestamp" followed by other columns sorter +// The first column will always be "timestamp" followed by other columns sorted // alphabetically. func (t *TopNRecord) Columns() []string { for _, result := range t.Result { From 2ceb550ec2ec927b6df9d78106e92db51362cbbd Mon Sep 17 00:00:00 2001 From: Kasia <24753130+ziomecka@users.noreply.github.com> Date: Tue, 7 Feb 2023 02:42:54 +0100 Subject: [PATCH 030/101] 8225 Fix missing grafana loader (#53) Co-authored-by: Katarzyna Ziomek-Zdanowicz --- .../dashboard/containers/DashboardPage.tsx | 17 ++++++++++++----- .../fn-dashboard-page/render-fn-dashboard.tsx | 7 ++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index bd1195ff81ce6..75022074734f8 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -1,5 +1,5 @@ import { cx } from '@emotion/css'; -import React, { PureComponent, ReactNode } from 'react'; +import React, { PureComponent, } from 'react'; import { connect, ConnectedProps, MapDispatchToProps, MapStateToProps } from 'react-redux'; import { NavModel, NavModelItem, TimeRange, PageLayoutType, locationUtil, GrafanaTheme2 } from '@grafana/data'; @@ -44,6 +44,8 @@ import { getTimeSrv } from '../services/TimeSrv'; import { explicitlyControlledMigrationPanels, autoMigrateAngular } from '../state/PanelModel'; import { cleanUpDashboardAndVariables } from '../state/actions'; import { initDashboard } from '../state/initDashboard'; +import { FNDashboardProps } from 'app/fn-app/types'; +import { isUndefined, isEmpty, noop } from 'lodash'; import { DashboardPageRouteParams, DashboardPageRouteSearchParams } from './types'; @@ -90,7 +92,8 @@ const connector = connect(mapStateToProps, mapDispatchToProps); type OwnProps = { isPublic?: boolean; controlsContainer?: string | null; - fnLoader?: ReactNode; + fnLoader?: FNDashboardProps['fnLoader']; + isLoading?: FNDashboardProps['isLoading'] }; export type DashboardPageProps = OwnProps & @@ -396,14 +399,18 @@ export class UnthemedDashboardPage extends PureComponent { }; render() { - const { dashboard, initError, queryParams, isPublic, FNDashboard, fnLoader } = this.props; + const { dashboard, initError, queryParams, isPublic, FNDashboard, fnLoader, isLoading = noop } = this.props; const { editPanel, viewPanel, updateScrollTop, pageNav, sectionNav } = this.state; const kioskMode = FNDashboard ? KioskMode.FN : !isPublic ? getKioskMode(this.props.queryParams) : KioskMode.Full; - if (!dashboard) { - return fnLoader ? <>{fnLoader} : ; + if (!dashboard || isEmpty(queryParams)) { + isLoading(true) + + return isUndefined(fnLoader) ? : <>{fnLoader}; } + isLoading(false) + const inspectPanel = this.getInspectPanel(); const showSubMenu = !editPanel && !this.props.queryParams.editview; diff --git a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx index 739b698e741c3..7959f70d54de7 100644 --- a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx @@ -1,4 +1,4 @@ -import { merge, isEmpty, isFunction } from 'lodash'; +import { merge, isFunction } from 'lodash'; import React, { useEffect, FC, useMemo } from 'react'; import { locationService as locationSrv, HistoryWrapper } from '@grafana/runtime'; @@ -27,7 +27,7 @@ const DEFAULT_DASHBOARD_PAGE_PROPS: Pick = (props) => { - const { queryParams, controlsContainer, setErrors, fnLoader, hiddenVariables } = props; + const { queryParams, controlsContainer, setErrors, fnLoader, hiddenVariables, isLoading } = props; const firstError = useSelector((state: StoreState) => { const { appNotifications } = state; @@ -67,9 +67,10 @@ export const RenderFNDashboard: FC = (props) => { hiddenVariables, controlsContainer, fnLoader, + isLoading }), [controlsContainer, fnLoader, hiddenVariables, props, queryParams] ); - return isEmpty(queryParams || {}) ? <>{fnLoader} : ; + return ; }; From 7eee0666994c879ffcbe0fe831bcd700c705d9ec Mon Sep 17 00:00:00 2001 From: Krzysztof Kwapisiewicz Date: Tue, 7 Feb 2023 10:58:02 +0100 Subject: [PATCH 031/101] Fix ad hoc filters (#54) --- .../grafadruid-druid-datasource/DruidDataSource.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/DruidDataSource.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/DruidDataSource.ts index 581b4e03be405..065121cc2c7dd 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/DruidDataSource.ts +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/DruidDataSource.ts @@ -178,8 +178,7 @@ export class DruidDataSource extends DataSourceWithBackend= '\${__from:date:iso}' AND __time <= '\${__to:date:iso}' GROUP BY 1`; const tagValuesQuery = { builder: { queryType: 'sql', From bbca5835f257edd4c436f47ff4f42109079aa847 Mon Sep 17 00:00:00 2001 From: Kasia <24753130+ziomecka@users.noreply.github.com> Date: Tue, 7 Feb 2023 20:44:34 +0100 Subject: [PATCH 032/101] 8238 Remove panel header menu (#55) Co-authored-by: Katarzyna Ziomek-Zdanowicz --- .../dashgrid/PanelHeader/PanelHeader.tsx | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx new file mode 100644 index 0000000000000..9431e752c4306 --- /dev/null +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx @@ -0,0 +1,124 @@ +import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; + +import { DataLink, GrafanaTheme2, PanelData } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Icon, useStyles2, ClickOutsideWrapper } from '@grafana/ui'; +import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; +import { PanelModel } from 'app/features/dashboard/state/PanelModel'; +import { getPanelLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers'; +import { StoreState, useSelector } from 'app/types'; + +import PanelHeaderCorner from './PanelHeaderCorner'; +import { PanelHeaderLoadingIndicator } from './PanelHeaderLoadingIndicator'; +import { PanelHeaderMenuTrigger } from './PanelHeaderMenuTrigger'; +import { PanelHeaderMenuWrapper } from './PanelHeaderMenuWrapper'; +import { PanelHeaderNotices } from './PanelHeaderNotices'; + +export interface Props { + panel: PanelModel; + dashboard: DashboardModel; + title?: string; + description?: string; + links?: DataLink[]; + error?: string; + alertState?: string; + isViewing: boolean; + isEditing: boolean; + data: PanelData; +} + +export const PanelHeader: FC = ({ panel, error, isViewing, isEditing, data, alertState, dashboard }) => { + + const isFnDashboard = useSelector((state: StoreState) => { + const { + fnGlobalState: { FNDashboard }, + } = state; + + return FNDashboard; + }); + + const onCancelQuery = () => panel.getQueryRunner().cancelQuery(); + const title = panel.getDisplayTitle(); + const className = cx('panel-header', !(isViewing || isEditing) ? 'grid-drag-handle' : ''); + const styles = useStyles2(panelStyles); + + return ( + <> + + +
+ + {({ closeMenu, panelMenuOpen }) => { + return ( + +
+ + {alertState ? ( + + ) : null} +

{title}

+ {isFnDashboard + ? null + : !dashboard.meta.publicDashboardAccessToken && ( +
+ + {panelMenuOpen ? ( + + ) : null} +
+ )} + {data.request && data.request.timeInfo && ( + + {data.request.timeInfo} + + )} +
+
+ ); + }} +
+
+ + ); +}; + +const panelStyles = (theme: GrafanaTheme2) => { + return { + fnPanelHeader: css` + &:hover { + background-color: initial!important; + cursor: default!important; + } + `, + titleText: css` + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + max-width: calc(100% - 38px); + cursor: pointer; + font-weight: ${theme.typography.fontWeightMedium}; + font-size: ${theme.typography.body.fontSize}; + margin: 0; + + &:hover { + color: ${theme.colors.text.primary}; + } + .panel-has-alert & { + max-width: calc(100% - 54px); + } + `, + }; +}; From 3ed3769bfea5ee47565848282f5f8b7cb9b89545 Mon Sep 17 00:00:00 2001 From: Gurinder Singh <108446046+gurinder39@users.noreply.github.com> Date: Wed, 15 Feb 2023 16:23:30 -0500 Subject: [PATCH 033/101] added presisted time range (#56) --- .../TimePicker/TimePickerWithHistory.tsx | 16 +++++++++++++--- public/app/core/reducers/fn-slice.ts | 4 +++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx index 7b0e68a7db828..f1db6534eb2ba 100644 --- a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx +++ b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx @@ -1,12 +1,13 @@ +import { merge, uniqBy } from 'lodash'; import React, { CSSProperties } from 'react'; -import { useSelector } from 'react-redux'; -import { uniqBy } from 'lodash'; +// eslint-disable-next-line no-restricted-imports +import { useDispatch, useSelector } from 'react-redux'; import { t } from '@grafana/ui/src/utils/i18n'; import appEvents from 'app/core/app_events'; import { TimeRange, isDateTime, rangeUtil, AppEvents } from '@grafana/data'; import { TimeRangePickerProps, TimeRangePicker, useTheme2 } from '@grafana/ui'; -import { FnGlobalState } from 'app/core/reducers/fn-slice'; +import { FnGlobalState, updatePartialFnStates } from 'app/core/reducers/fn-slice'; import { StoreState } from 'app/types'; import { LocalStorageValueProvider } from '../LocalStorageValueProvider'; @@ -35,6 +36,9 @@ const FnText: React.FC = () => { }; export const TimePickerWithHistory: React.FC = (props) => { + const { fnGlobalTimeRange } = useSelector(({ fnGlobalState }) => fnGlobalState); + const dispatch = useDispatch(); + return ( storageKey={LOCAL_STORAGE_KEY} defaultValue={[]}> {(rawValues, onSaveToStore) => { @@ -45,7 +49,13 @@ export const TimePickerWithHistory: React.FC = (props) => { { + dispatch( + updatePartialFnStates({ + fnGlobalTimeRange: value, + }) + ); onAppendToHistory(value, values, onSaveToStore); props.onChange(value); }} diff --git a/public/app/core/reducers/fn-slice.ts b/public/app/core/reducers/fn-slice.ts index 0d9128ade0ae6..d977b2b3635dd 100644 --- a/public/app/core/reducers/fn-slice.ts +++ b/public/app/core/reducers/fn-slice.ts @@ -1,6 +1,6 @@ import { createSlice, PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit'; -import { GrafanaThemeType } from '@grafana/data'; +import { GrafanaThemeType, TimeRange } from '@grafana/data'; import { AnyObject } from '../../fn-app/types'; @@ -13,6 +13,7 @@ export interface FnGlobalState { pageTitle: string; queryParams: AnyObject; hiddenVariables: readonly string[]; + fnGlobalTimeRange: TimeRange | null; } export type UpdateFNGlobalStateAction = PayloadAction>; @@ -55,6 +56,7 @@ export const INITIAL_FN_STATE: FnGlobalState = { pageTitle: '', queryParams: {}, hiddenVariables: [], + fnGlobalTimeRange: null, } as const; const reducers: SliceCaseReducers = { From 366cb2203091580e0761db2757073f1fc1f4ec8c Mon Sep 17 00:00:00 2001 From: Hardik Shingala <34568645+hdkshingala@users.noreply.github.com> Date: Fri, 17 Feb 2023 16:07:24 +0530 Subject: [PATCH 034/101] Updates to latest instead of demo environment (#57) --- .circleci/config.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fd57a2257c31f..f8d92c9a92f9d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -259,18 +259,7 @@ workflows: - fluxninja_micro_frontends requires: - image-build-grafana-alpine - environment-path: environments/demo/ - component: grafana - update: images - - update-environment: - name: update-nightly-environment - filters: - branches: - only: - - fluxninja_micro_frontends - requires: - - image-build-grafana-alpine - environment-path: environments/nightly/ + environment-path: environments/latest/ component: grafana update: images From 7caf01934db416f737785a7ad155de594e415368 Mon Sep 17 00:00:00 2001 From: Gurinder Singh <108446046+gurinder39@users.noreply.github.com> Date: Thu, 23 Feb 2023 17:45:00 -0500 Subject: [PATCH 035/101] Loading dashboards with update function (#58) * changed dashboard loading to use update fn * removed extra package --- public/app/core/reducers/fn-slice.ts | 5 +++- .../dashboard/containers/DashboardPage.tsx | 4 ++-- .../dashboard/dashgrid/DashboardPanel.tsx | 23 +++++++------------ .../dashboard/dashgrid/PanelStateWrapper.tsx | 13 +++-------- public/app/fn-app/create-mfe.ts | 17 +++++++------- .../fn-app/fn-dashboard-page/fn-dashboard.tsx | 10 ++------ .../fn-dashboard-page/render-fn-dashboard.tsx | 2 +- public/app/fn-app/utils.tsx | 4 ---- 8 files changed, 28 insertions(+), 50 deletions(-) diff --git a/public/app/core/reducers/fn-slice.ts b/public/app/core/reducers/fn-slice.ts index d977b2b3635dd..d6d6c0949d060 100644 --- a/public/app/core/reducers/fn-slice.ts +++ b/public/app/core/reducers/fn-slice.ts @@ -20,7 +20,7 @@ export type UpdateFNGlobalStateAction = PayloadAction>; export type SetFnStateAction = PayloadAction>; -export type FnPropMappedFromState = Extract; +export type FnPropMappedFromState = Extract; export type FnStateProp = keyof FnGlobalState; export type FnPropsMappedFromState = Pick; @@ -40,6 +40,9 @@ export const fnPropsMappedFromState: readonly FnPropMappedFromState[] = [ 'FNDashboard', 'hiddenVariables', 'mode', + 'uid', + 'queryParams', + 'slug', ] as const; const INITIAL_MODE = GrafanaThemeType.Light; diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index 75022074734f8..6e1b876c8fcd5 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -1,4 +1,5 @@ import { cx } from '@emotion/css'; +import { isUndefined, isEmpty, noop } from 'lodash'; import React, { PureComponent, } from 'react'; import { connect, ConnectedProps, MapDispatchToProps, MapStateToProps } from 'react-redux'; @@ -22,6 +23,7 @@ import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; import { AngularDeprecationNotice } from 'app/features/plugins/angularDeprecation/AngularDeprecationNotice'; import { AngularMigrationNotice } from 'app/features/plugins/angularDeprecation/AngularMigrationNotice'; import { getPageNavFromSlug, getRootContentNavModel } from 'app/features/storage/StorageFolderPage'; +import { FNDashboardProps } from 'app/fn-app/types'; import { RenderPortal } from 'app/fn-app/utils'; import { DashboardRoutes, DashboardState, KioskMode, StoreState } from 'app/types'; import { PanelEditEnteredEvent, PanelEditExitedEvent } from 'app/types/events'; @@ -44,8 +46,6 @@ import { getTimeSrv } from '../services/TimeSrv'; import { explicitlyControlledMigrationPanels, autoMigrateAngular } from '../state/PanelModel'; import { cleanUpDashboardAndVariables } from '../state/actions'; import { initDashboard } from '../state/initDashboard'; -import { FNDashboardProps } from 'app/fn-app/types'; -import { isUndefined, isEmpty, noop } from 'lodash'; import { DashboardPageRouteParams, DashboardPageRouteSearchParams } from './types'; diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index b0873eabb0712..1f4afad770c64 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -34,6 +34,7 @@ const mapStateToProps = (state: StoreState, props: OwnProps) => { return { plugin: panelState.plugin, instanceState: panelState.instanceState, + fnGlobalState: state.fnGlobalState }; }; @@ -45,8 +46,8 @@ const mapDispatchToProps = { const connector = connect(mapStateToProps, mapDispatchToProps); export type Props = OwnProps & ConnectedProps; - export class DashboardPanelUnconnected extends PureComponent { + static defaultProps: Partial = { lazy: true, }; @@ -72,19 +73,10 @@ export class DashboardPanelUnconnected extends PureComponent { } }; - renderPanel = ({ isInView }: { isInView: boolean }) => { - const { - dashboard, - panel, - isViewing, - isEditing, - width, - height, - plugin, - timezone, - hideMenu, - isDraggable = true, - } = this.props; + renderPanel = (isInView: boolean) => { + const { dashboard, panel, isViewing, isEditing, width, height, plugin, timezone, fnGlobalState, isDraggable = true } = this.props; + + // console.log(this.props, "on render panel") if (!plugin) { return null; @@ -119,7 +111,8 @@ export class DashboardPanelUnconnected extends PureComponent { height={height} onInstanceStateChange={this.onInstanceStateChange} timezone={timezone} - hideMenu={hideMenu} + mode={fnGlobalState.mode} + FNDashboard={fnGlobalState.FNDashboard} /> ); }; diff --git a/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx b/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx index 2448f85dd3dc4..6c93b986c6c60 100644 --- a/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx +++ b/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx @@ -1,6 +1,5 @@ import classNames from 'classnames'; import React, { PureComponent, CSSProperties } from 'react'; -import { connect } from 'react-redux'; import { Subscription } from 'rxjs'; import { @@ -41,7 +40,6 @@ import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { applyFilterFromTable } from 'app/features/variables/adhoc/actions'; import { onUpdatePanelSnapshotData } from 'app/plugins/datasource/grafana/utils'; import { changeSeriesColorConfigFactory } from 'app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory'; -import { StoreState } from 'app/types'; import { RenderEvent } from 'app/types/events'; import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../annotations/api'; @@ -73,6 +71,7 @@ export interface Props { timezone?: string; hideMenu?: boolean; FNDashboard?: boolean; + mode?: "light" | "dark"; } export interface State { @@ -296,6 +295,7 @@ export class PanelStateWrapper extends PureComponent { if (width !== prevProps.width) { liveTimer.updateInterval(this); } + } // Updates the response with information from the stream @@ -613,8 +613,7 @@ export class PanelStateWrapper extends PureComponent { aria-label={selectors.components.Panels.Panel.containerByTitle(panel.title)} > {FNDashboard ? ( - // TODO: Avoid divology. Use HTML5, i.e. wrap texts with p or h element instead of div. -
{panel.title}
+

{panel.title}

) : ( { } } } - -const mapStateToProps = (state: StoreState) => { - return { ...state.fnGlobalState }; -}; -const connector = connect(mapStateToProps); -export const PanelChrome = connector(PanelStateWrapper); diff --git a/public/app/fn-app/create-mfe.ts b/public/app/fn-app/create-mfe.ts index 09c1084dba386..365b12cdd9223 100644 --- a/public/app/fn-app/create-mfe.ts +++ b/public/app/fn-app/create-mfe.ts @@ -264,14 +264,10 @@ class createMfe { } static updateFnApp() { - const lifeCycleFn: FrameworkLifeCycles['update'] = ({ mode, hiddenVariables }: FNDashboardProps) => { + const lifeCycleFn: FrameworkLifeCycles['update'] = ({ mode, ...other }: FNDashboardProps) => { if (mode) { createMfe.logger('Trying to update grafana with theme.', { mode }); - /** - * NOTE - * We do not use the "mode" state right now, - * but I believe that as long as we store the "mode, we should update it - */ + dispatch( updatePartialFnStates({ mode, @@ -288,12 +284,15 @@ class createMfe { createMfe.loadFnTheme(mode); } - if (hiddenVariables) { - createMfe.logger('Trying to update grafana with hidden variables.', { hiddenVariables }); + if (other.uid) { + createMfe.logger('Trying to update grafana with hidden variables.', { updatedProps: other }); dispatch( updatePartialFnStates({ - hiddenVariables, + uid: other.uid, + hiddenVariables: other.hiddenVariables, + slug: other.slug, + queryParams: other.queryParams, }) ); } diff --git a/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx index e861fe9ae1545..24f9051077ad5 100644 --- a/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx @@ -1,9 +1,7 @@ import { pick } from 'lodash'; -import { parse as parseQueryParams } from 'query-string'; import React, { FC, Suspense, useMemo } from 'react'; import { lazily } from 'react-lazily'; import { connect, MapStateToProps } from 'react-redux'; -import { useLocation } from 'react-router-dom'; import { FnGlobalState, @@ -44,7 +42,6 @@ function mapStateToProps(): MapStateToProps< } export const DashboardPortalComponent: FC = (props) => { - const location = useLocation(); const content = useMemo(() => { if (!props.FNDashboard) { @@ -52,10 +49,7 @@ export const DashboardPortalComponent: FC ); - }, [location, props]); + }, [props]); return {content}; }; diff --git a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx index 7959f70d54de7..26c47528905d9 100644 --- a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx @@ -69,7 +69,7 @@ export const RenderFNDashboard: FC = (props) => { fnLoader, isLoading }), - [controlsContainer, fnLoader, hiddenVariables, props, queryParams] + [controlsContainer, fnLoader, hiddenVariables, isLoading, props, queryParams] ); return ; diff --git a/public/app/fn-app/utils.tsx b/public/app/fn-app/utils.tsx index 8ad2a580fb663..c7599d2d49166 100644 --- a/public/app/fn-app/utils.tsx +++ b/public/app/fn-app/utils.tsx @@ -5,10 +5,6 @@ export interface RenderPortalProps { ID: string; } -export declare type PortalEffectReturn = { - portalDiv: HTMLElement | null; -} - export const getPortalContainer = (ID: string): HTMLElement | null => document.getElementById(ID); export const RenderPortal: FC = ({ ID, children }) => { From 26f66bb432caf88d71108bf6548a8e0950f2c404 Mon Sep 17 00:00:00 2001 From: Gurinder Singh <108446046+gurinder39@users.noreply.github.com> Date: Mon, 6 Mar 2023 17:47:12 -0500 Subject: [PATCH 036/101] changed query filter designs (#59) --- .../dashboard/components/SubMenu/SubMenu.tsx | 25 +++++++-- .../variables/pickers/PickerRenderer.tsx | 52 +++++++++++++++---- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx index 4d9af8a0e82dc..d864104bdc7e6 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx @@ -1,6 +1,7 @@ import { css } from '@emotion/css'; -import { PureComponent } from 'react'; -import * as React from 'react'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import { Box, styled } from '@mui/material'; +import React, { FC, PureComponent } from 'react'; import { connect, MapStateToProps } from 'react-redux'; import { AnnotationQuery, DataQuery, TypedVariableModel, GrafanaTheme2 } from '@grafana/data'; @@ -13,7 +14,7 @@ import { DashboardModel } from '../../state'; import { Annotations } from './Annotations'; import { DashboardLinks } from './DashboardLinks'; import { SubMenuItems } from './SubMenuItems'; -import { VariableModel } from 'app/features/variables/types'; +// import { VariableModel } from 'app/features/variables/types'; import { Themeable2, stylesFactory, withTheme2 } from '@grafana-ui'; import { DashboardLink } from '@grafana/schema/dist/esm/index'; @@ -60,6 +61,7 @@ class SubMenuUnConnected extends PureComponent { return (
+ { export const SubMenu = withTheme2(connect(mapStateToProps)(SubMenuUnConnected)); SubMenu.displayName = 'SubMenu'; + +const FilterWithIcon: FC = () => ( + + + FILTERS + +); + +const FilterWithIconStyled = styled(Box)({ + display: 'flex', + gap: 1, + alignItems: 'center', + color: '#3A785E', + fontWeight: 600, + lineHeight: '160%', + fontSize: 12, +}); diff --git a/public/app/features/variables/pickers/PickerRenderer.tsx b/public/app/features/variables/pickers/PickerRenderer.tsx index 4f82d38fb25c5..b0ccfbfc682a1 100644 --- a/public/app/features/variables/pickers/PickerRenderer.tsx +++ b/public/app/features/variables/pickers/PickerRenderer.tsx @@ -1,9 +1,12 @@ +import { css } from '@emotion/css'; import React, { CSSProperties, FunctionComponent, PropsWithChildren, ReactElement, useMemo } from 'react'; +import { Stack } from '@mui/material'; +// eslint-disable-next-line no-restricted-imports import { useSelector } from 'react-redux'; import { TypedVariableModel, VariableHide } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { Tooltip, useTheme2 } from '@grafana/ui'; +import { Tooltip } from '@grafana/ui'; import { FnGlobalState } from 'app/core/reducers/fn-slice'; import type { StoreState } from 'app/types'; @@ -15,7 +18,19 @@ interface Props { readOnly?: boolean; } -export const PickerRenderer = (props: Props) => { +const renderWrapperStyle = css` + & button, + & span, + & label, + & input { + height: 24px; + font-size: 12px; + line-height: 24px; + align-self: center; + } +`; + +export const PickerRenderer: FunctionComponent = (props) => { const PickerToRender = useMemo(() => variableAdapters.get(props.variable.type).picker, [props.variable]); if (!props.variable) { @@ -26,28 +41,45 @@ export const PickerRenderer = (props: Props) => { {props.variable.hide !== VariableHide.hideVariable && PickerToRender && ( - +
+ +
)}
); }; const COMMON_PICKER_LABEL_STYLE: CSSProperties = { - borderRadius: '4px', + borderRadius: '2px', border: 'none', - fontWeight: 600, + fontWeight: 400, fontSize: '12px', + padding: '3px 6px', + letterSpacing: '0.15px', + height: '24px', }; function PickerLabel({ variable }: PropsWithChildren): ReactElement | null { const labelOrName = useMemo(() => variable.label || variable.name, [variable]); - const { FNDashboard } = useSelector(({ fnGlobalState }) => fnGlobalState); - const theme = useTheme2(); + const { FNDashboard, mode } = useSelector(({ fnGlobalState }) => fnGlobalState); + + const fnLabelStyle = useMemo( + () => ({ + ...COMMON_PICKER_LABEL_STYLE, + ...(FNDashboard + ? { + color: mode === 'light' ? '#2D333E' : '#DBD9D7', + backgroundColor: mode === 'light' ? '#E0E0E0' : '#56524D', + } + : {}), + }), + [mode, FNDashboard] + ); if (variable.hide !== VariableHide.dontHide) { return null; } - const fnLabelOrName = FNDashboard ? labelOrName.replace('druid', '') : labelOrName; + const fnLabelOrName = FNDashboard ? labelOrName.replace('druid_adhoc_filters', 'ad-hoc') : labelOrName; const elementId = VARIABLE_PREFIX + variable.id; if (variable.description) { @@ -55,7 +87,7 @@ function PickerLabel({ variable }: PropsWithChildren): ReactElement | nul
%M?;geSO?bRIkyUr3O%dPZJr)3>dL82v86 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 - - - diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/module.test.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/module.test.ts deleted file mode 100644 index 5e199ed0fa738..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/module.test.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe('placeholder test', () => { - it('should return true', () => { - expect(true).toBeTruthy(); - }); -}); diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/partials/annotations.editor.html b/public/app/plugins/datasource/fifemon-graphql-datasource/partials/annotations.editor.html deleted file mode 100644 index 99824c44211fe..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/partials/annotations.editor.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - -
-
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
-
- - diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/plugin.json b/public/app/plugins/datasource/fifemon-graphql-datasource/plugin.json deleted file mode 100644 index cf5a57a9fa2e3..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/plugin.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "type": "datasource", - "name": "GraphQL Data Source", - "id": "fifemon-graphql-datasource", - "metrics": true, - "annotations": true, - - "info": { - "description": "GraphQL Data Source", - "author": { - "name": "Kevin Retzke" - }, - "keywords": ["GraphQL"], - "logos": { - "small": "img/logo.svg", - "large": "img/logo.svg" - }, - "links": [ - { "name": "Website", "url": "https://github.com/fifemon/graphql-datasource" }, - { "name": "License", "url": "https://github.com/fifemon/graphql-datasource/blob/master/LICENSE" } - ], - "screenshots": [ - { "name": "DeutscheBahn Arrivals", "path": "img/db_arrivals.png"}, - { "name": "DeutscheBahn Arrivals Annotations", "path": "img/db_arrivals_annotations.png"}, - { "name": "GitHub Security Advisories", "path": "img/github_security_advisories.png"} - ], - "version": "%VERSION%", - "updated": "%TODAY%" - }, - - "dependencies": { - "grafanaVersion": "7.x.x", - "grafanaDependency": ">=7.0.0", - "plugins": [] - } -} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/types.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/types.ts deleted file mode 100644 index 4b4819512a3a2..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/types.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { DataQuery, DataSourceJsonData, VariableModel } from '@grafana/data'; - -export interface MyQuery extends DataQuery { - queryText: string; - dataPath: string; - timePath: string; - endTimePath: string | null; - timeFormat: string | null; - groupBy: string; - aliasBy: string; - annotationTitle: string; - annotationText: string; - annotationTags: string; - constant: number; -} - -export const defaultQuery: Partial = { - queryText: `query { - data:submissions(user:"$user"){ - Time:submitTime - idle running completed - } -}`, - dataPath: 'data', - timePath: 'Time', - endTimePath: 'endTime', - timeFormat: null, - groupBy: '', // `identifier` - aliasBy: '', // 'Server [[tag_identifier]]` - annotationTitle: '', - annotationText: '', - annotationTags: '', - constant: 6.5, -}; - -/** - * These are options configured for each DataSource instance - */ -export interface MyDataSourceOptions extends DataSourceJsonData { - apiKey?: string; -} - -export interface MyVariableQuery extends DataQuery { - dataPath: string; - queryText: string; -} - -export interface TextValuePair { - text: string; - value: any; -} - -export interface MultiValueVariable extends VariableModel { - allValue: string | null; - id: string; - current: TextValuePair; - options: TextValuePair[]; -} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/util.test.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/util.test.ts deleted file mode 100644 index c91386f359147..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/util.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { flatten, isRFC3339_ISO6801 } from './util'; - -test('flatten function test', () => { - let obj = { - string: 'hello', - number: 123, - float: 123.4, - null: null, - undefined: undefined, - array: [1, 2, 3], - nested: { - string: 'hello', - number: 123, - float: 123.4, - null: null, - undefined: undefined, - }, - }; - - let flattenObj = { - string: 'hello', - number: 123, - float: 123.4, - null: null, - undefined: undefined, - 'array.0': 1, - 'array.1': 2, - 'array.2': 3, - 'nested.string': 'hello', - 'nested.number': 123, - 'nested.float': 123.4, - 'nested.null': null, - 'nested.undefined': undefined, - }; - - expect(flatten(obj)).toEqual(flattenObj); -}); - -test('RFC3339 and ISO8601 valid string test', () => { - expect(isRFC3339_ISO6801('I am not a date but a string')).toBe(false); - expect(isRFC3339_ISO6801('1234')).toBe(false); - expect(isRFC3339_ISO6801(String(8))).toBe(false); - expect(isRFC3339_ISO6801(String(null))).toBe(false); - expect(isRFC3339_ISO6801('2020-06-01T00:00:00.000Z')).toBe(true); - expect(isRFC3339_ISO6801('2020-06-01T00:00:00Z')).toBe(true); - expect(isRFC3339_ISO6801(String(true))).toBe(false); - expect(isRFC3339_ISO6801(String(0))).toBe(false); - expect(isRFC3339_ISO6801(String(Number.MAX_SAFE_INTEGER))).toBe(false); - expect(isRFC3339_ISO6801(String(0.111111))).toBe(false); - expect(isRFC3339_ISO6801(String(1603810963000))).toBe(false); -}); diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/util.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/util.ts deleted file mode 100644 index e3f586668514c..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/util.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { dateTime, ISO_8601 } from '@grafana/data'; - -export function flatten>(object: T, path: string | null = null, separator = '.'): T { - return Object.keys(object).reduce((acc: T, key: string): T => { - const isObject = typeof object[key] === 'object' && object[key] != null; - const newPath = [path, key].filter(Boolean).join(separator); - return isObject ? { ...acc, ...flatten(object[key], newPath, separator) } : { ...acc, [newPath]: object[key] }; - }, {} as T); -} - -export function isRFC3339_ISO6801(str: string): boolean { - let date = dateTime(str, ISO_8601); - if (date.isValid()) { - let iso = date.toISOString(); - if (iso === str) { - return true; - } else { - // some RFC3339 dates don't include fractions of a second to same resolution, but still valid. - return iso.substring(0, 19) === str.substring(0, 19); - } - } - return false; -} From 931022ce6b27f91768288e62a11aa65ed1d2b84b Mon Sep 17 00:00:00 2001 From: Jaseel <12792882+Spikatrix@users.noreply.github.com> Date: Thu, 19 Oct 2023 17:26:51 +0530 Subject: [PATCH 068/101] Enable panel resizing (#105) --- .../dashboard/dashgrid/DashboardGrid.tsx | 215 ++++++------------ 1 file changed, 73 insertions(+), 142 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index cb09e66048aa4..252381314fee4 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -1,17 +1,18 @@ import classNames from 'classnames'; -import { PureComponent, CSSProperties } from 'react'; -import * as React from 'react'; +import React, { PureComponent, CSSProperties } from 'react'; import ReactGridLayout, { ItemCallback } from 'react-grid-layout'; +import { connect } from 'react-redux'; +import AutoSizer from 'react-virtualized-auto-sizer'; import { Subscription } from 'rxjs'; import { config } from '@grafana/runtime'; -import appEvents from 'app/core/app_events'; import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT } from 'app/core/constants'; import { contextSrv } from 'app/core/services/context_srv'; -import { VariablesChanged } from 'app/features/variables/types'; +import { StoreState } from 'app/types'; import { DashboardPanelsChangedEvent } from 'app/types/events'; import { AddLibraryPanelWidget } from '../components/AddLibraryPanelWidget'; +import { AddPanelWidget } from '../components/AddPanelWidget'; import { DashboardRow } from '../components/DashboardRow'; import { DashboardModel, PanelModel } from '../state'; import { GridPos } from '../state/PanelModel'; @@ -19,22 +20,16 @@ import { GridPos } from '../state/PanelModel'; import DashboardEmpty from './DashboardEmpty'; import { DashboardPanel } from './DashboardPanel'; -export const PANEL_FILTER_VARIABLE = 'systemPanelFilterVar'; - export interface Props { dashboard: DashboardModel; isEditable: boolean; editPanel: PanelModel | null; viewPanel: PanelModel | null; hidePanelMenus?: boolean; + isFnDashboard?: boolean; } -interface State { - panelFilter?: RegExp; - width: number; -} - -export class DashboardGrid extends PureComponent { +export class Component extends PureComponent { private panelMap: { [key: string]: PanelModel } = {}; private eventSubs = new Subscription(); private windowHeight = 1200; @@ -46,41 +41,10 @@ export class DashboardGrid extends PureComponent { constructor(props: Props) { super(props); - this.state = { - panelFilter: undefined, - width: document.body.clientWidth, // initial very rough estimate - }; } componentDidMount() { const { dashboard } = this.props; - - if (config.featureToggles.panelFilterVariable) { - // If panel filter variable is set on load then - // update state to filter panels - for (const variable of dashboard.getVariables()) { - if (variable.id === PANEL_FILTER_VARIABLE) { - if ('query' in variable) { - this.setPanelFilter(variable.query); - } - break; - } - } - - this.eventSubs.add( - appEvents.subscribe(VariablesChanged, (e) => { - if (e.payload.variable?.id === PANEL_FILTER_VARIABLE) { - if ('current' in e.payload.variable) { - let variable = e.payload.variable.current; - if ('value' in variable && typeof variable.value === 'string') { - this.setPanelFilter(variable.value); - } - } - } - }) - ); - } - this.eventSubs.add(dashboard.events.subscribe(DashboardPanelsChangedEvent, this.triggerForceUpdate)); } @@ -88,25 +52,10 @@ export class DashboardGrid extends PureComponent { this.eventSubs.unsubscribe(); } - setPanelFilter(regex: string) { - // Only set the panels filter if the systemPanelFilterVar variable - // is a non-empty string - let panelFilter = undefined; - if (regex.length > 0) { - panelFilter = new RegExp(regex, 'i'); - } - - this.setState({ - panelFilter: panelFilter, - }); - } - buildLayout() { const layout: ReactGridLayout.Layout[] = []; this.panelMap = {}; - const { panelFilter } = this.state; - let count = 0; for (const panel of this.props.dashboard.panels) { if (!panel.key) { panel.key = `panel-${panel.id}-${Date.now()}`; @@ -133,27 +82,13 @@ export class DashboardGrid extends PureComponent { panelPos.isDraggable = panel.collapsed; } - if (!panelFilter) { - layout.push(panelPos); - } else { - if (panelFilter.test(panel.title)) { - panelPos.isResizable = false; - panelPos.isDraggable = false; - panelPos.x = (count % 2) * GRID_COLUMN_COUNT; - panelPos.y = Math.floor(count / 2); - layout.push(panelPos); - count++; - } - } + layout.push(panelPos); } return layout; } onLayoutChange = (newLayout: ReactGridLayout.Layout[]) => { - if (this.state.panelFilter) { - return; - } for (const newPos of newLayout) { this.panelMap[newPos.i!].updateGridPos(newPos, this.isLayoutInitialized); } @@ -205,7 +140,6 @@ export class DashboardGrid extends PureComponent { } renderPanels(gridWidth: number, isDashboardDraggable: boolean) { - const { panelFilter } = this.state; const panelElements = []; // Reset last panel bottom @@ -222,7 +156,7 @@ export class DashboardGrid extends PureComponent { for (const panel of this.props.dashboard.panels) { const panelClasses = classNames({ 'react-grid-item--fullscreen': panel.isViewing }); - const p = ( + panelElements.push( { }} ); - - if (!panelFilter) { - panelElements.push(p); - } else { - if (panelFilter.test(panel.title)) { - panelElements.push(p); - } - } } return panelElements; @@ -256,6 +182,11 @@ export class DashboardGrid extends PureComponent { return ; } + // Todo: Remove this when we remove the emptyDashboardPage toggle + if (panel.type === 'add-panel') { + return ; + } + if (panel.type === 'add-library-panel') { return ; } @@ -288,69 +219,61 @@ export class DashboardGrid extends PureComponent { } }; - private resizeObserver?: ResizeObserver; - private rootEl: HTMLDivElement | null = null; - onMeasureRef = (rootEl: HTMLDivElement | null) => { - if (!rootEl) { - if (this.rootEl && this.resizeObserver) { - this.resizeObserver.unobserve(this.rootEl); - } - return; - } - - this.rootEl = rootEl; - this.resizeObserver = new ResizeObserver((entries) => { - entries.forEach((entry) => { - this.setState({ width: entry.contentRect.width }); - }); - }); - - this.resizeObserver.observe(rootEl); - }; - render() { - const { isEditable, dashboard } = this.props; - const { width } = this.state; + const { isEditable, dashboard, isFnDashboard } = this.props; - if (dashboard.panels.length === 0) { + if (config.featureToggles.emptyDashboardPage && dashboard.panels.length === 0) { return ; } - const draggable = width <= config.theme2.breakpoints.values.md ? false : isEditable; - - // pos: rel + z-index is required to create a new stacking context to contain - // the escalating z-indexes of the panels + /** + * We have a parent with "flex: 1 1 0" we need to reset it to "flex: 1 1 auto" to have the AutoSizer + * properly working. For more information go here: + * https://github.com/bvaughn/react-virtualized/blob/master/docs/usingAutoSizer.md#can-i-use-autosizer-within-a-flex-container + */ return ( -
-
- - {this.renderPanels(width, draggable)} - -
+
+ + {({ width }) => { + if (width === 0) { + return null; + } + + // Disable draggable if mobile device, solving an issue with unintentionally + // moving panels. https://github.com/grafana/grafana/issues/18497 + const isLg = width <= config.theme2.breakpoints.values.md; + const draggable = isLg ? false : isEditable; + + return ( + /** + * The children is using a width of 100% so we need to guarantee that it is wrapped + * in an element that has the calculated size given by the AutoSizer. The AutoSizer + * has a width of 0 and will let its content overflow its div. + */ +
+ + {this.renderPanels(width, draggable)} + +
+ ); + }} +
); } @@ -362,7 +285,7 @@ interface GrafanaGridItemProps extends React.HTMLAttributes { isViewing: boolean; windowHeight: number; windowWidth: number; - children: any; // eslint-disable-line @typescript-eslint/no-explicit-any + children: any; } /** @@ -403,7 +326,7 @@ const GrafanaGridItem = React.forwardRef(( // props.children[0] is our main children. RGL adds the drag handle at props.children[1] return ( -
+
{/* Pass width and height to children as render props */} {[props.children[0](width, height), props.children.slice(1)]}
@@ -418,3 +341,11 @@ function translateGridHeightToScreenHeight(gridHeight: number): number { } GrafanaGridItem.displayName = 'GridItemWithDimensions'; + +function mapStateToProps() { + return (state: StoreState) => ({ + isFnDashboard: state.fnGlobalState.FNDashboard, + }); +} + +export const DashboardGrid = connect(mapStateToProps)(Component); From 15c970bc42051df02591faf31f9b92780aee5525 Mon Sep 17 00:00:00 2001 From: Jaseel <12792882+Spikatrix@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:30:51 +0530 Subject: [PATCH 069/101] Adhoc filter fix, update sankey plugin (#106) * Adhoc filter style fix * Update sankey plugin --- packages/grafana-ui/src/themes/mixins.ts | 6 +- .../plugins/panel/sankey-panel-0.5.0/logo.svg | 20 - .../panel/sankey-panel-0.5.0/module.js | 1360 ++++++++++++++++- .../panel/sankey-panel-0.5.0/module.js.map | 2 +- .../panel/sankey-panel-0.5.0/plugin.json | 2 +- public/microfrontends/fn_dashboard/index.html | 2 +- 6 files changed, 1364 insertions(+), 28 deletions(-) delete mode 100644 public/app/plugins/panel/sankey-panel-0.5.0/logo.svg diff --git a/packages/grafana-ui/src/themes/mixins.ts b/packages/grafana-ui/src/themes/mixins.ts index 39351ce75019c..537ccaea44c51 100644 --- a/packages/grafana-ui/src/themes/mixins.ts +++ b/packages/grafana-ui/src/themes/mixins.ts @@ -39,16 +39,16 @@ export function mediaUp(breakpoint: string) { return `only screen and (min-width: ${breakpoint})`; } -// const isGrafanaTheme2 = (theme: GrafanaTheme | GrafanaTheme2): theme is GrafanaTheme2 => theme.hasOwnProperty('v1'); +const isGrafanaTheme2 = (theme: GrafanaTheme | GrafanaTheme2): theme is GrafanaTheme2 => theme.hasOwnProperty('v1'); export const focusCss = (theme: GrafanaTheme | GrafanaTheme2) => { - /* const isTheme2 = isGrafanaTheme2(theme); + const isTheme2 = isGrafanaTheme2(theme); const firstColor = isTheme2 ? theme.colors.background.canvas : theme.colors.bodyBg; const secondColor = isTheme2 ? theme.colors.primary.main : theme.colors.formFocusOutline; - box-shadow: 0 0 0 2px ${firstColor}, 0 0 0px 4px ${secondColor}; */ return ` outline: 2px dotted transparent; outline-offset: 2px; + box-shadow: 0 0 0 2px ${firstColor}, 0 0 0px 4px ${secondColor}; transition-property: outline, outline-offset, box-shadow; transition-duration: 0.2s; transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);`; diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/logo.svg b/public/app/plugins/panel/sankey-panel-0.5.0/logo.svg deleted file mode 100644 index 2d41fa5441e64..0000000000000 --- a/public/app/plugins/panel/sankey-panel-0.5.0/logo.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/module.js b/public/app/plugins/panel/sankey-panel-0.5.0/module.js index 9b8245b79e190..ac5c5013f822e 100644 --- a/public/app/plugins/panel/sankey-panel-0.5.0/module.js +++ b/public/app/plugins/panel/sankey-panel-0.5.0/module.js @@ -1,3 +1,1359 @@ /*! For license information please see module.js.LICENSE.txt */ -define(["react","d3","@grafana/data","@grafana/ui"],(function(t,e,n,r){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=5)}([function(e,n){e.exports=t},function(t,n){t.exports=e},function(t,e){t.exports=n},function(t,e){t.exports=r},,function(t,e,n){"use strict";n.r(e);var r={};n.r(r),n.d(r,"sankey",(function(){return M})),n.d(r,"sankeyCenter",(function(){return v})),n.d(r,"sankeyLeft",(function(){return g})),n.d(r,"sankeyRight",(function(){return p})),n.d(r,"sankeyJustify",(function(){return _})),n.d(r,"sankeyLinkHorizontal",(function(){return q}));var o=n(2);var i=function(){return(i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0)&&!(r=i.next()).done;)a.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a}var u=n(0),l=n.n(u),c=n(1);function f(t,e){let n=0;if(void 0===e)for(let e of t)(e=+e)&&(n+=e);else{let r=-1;for(let o of t)(o=+e(o,++r,t))&&(n+=o)}return n}function h(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n=e)&&(n=e);else{let r=-1;for(let o of t)null!=(o=e(o,++r,t))&&(n=o)&&(n=o)}return n}function d(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n>e||void 0===n&&e>=e)&&(n=e);else{let r=-1;for(let o of t)null!=(o=e(o,++r,t))&&(n>o||void 0===n&&o>=o)&&(n=o)}return n}function y(t){return t.target.depth}function g(t){return t.depth}function p(t,e){return e-1-t.height}function _(t,e){return t.sourceLinks.length?t.depth:e-1}function v(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?d(t.sourceLinks,y)-1:0}function k(t){return function(){return t}}function m(t,e){return x(t.source,e.source)||t.index-e.index}function b(t,e){return x(t.target,e.target)||t.index-e.index}function x(t,e){return t.y0-e.y0}function w(t){return t.value}function S(t){return t.index}function L(t){return t.nodes}function A(t){return t.links}function O(t,e){const n=t.get(e);if(!n)throw new Error("missing: "+e);return n}function j({nodes:t}){for(const e of t){let t=e.y0,n=t;for(const n of e.sourceLinks)n.y0=t+n.width/2,t+=n.width;for(const t of e.targetLinks)t.y1=n+t.width/2,n+=t.width}}function M(){let t,e,n,r=0,o=0,i=1,a=1,s=24,u=8,l=S,c=_,y=L,g=A,p=6;function v(){const t={nodes:y.apply(null,arguments),links:g.apply(null,arguments)};return M(t),T(t),V(t),P(t),E(t),j(t),t}function M({nodes:t,links:e}){for(const[e,n]of t.entries())n.index=e,n.sourceLinks=[],n.targetLinks=[];const r=new Map(t.map((e,n)=>[l(e,n,t),e]));for(const[t,n]of e.entries()){n.index=t;let{source:e,target:o}=n;"object"!=typeof e&&(e=n.source=O(r,e)),"object"!=typeof o&&(o=n.target=O(r,o)),e.sourceLinks.push(n),o.targetLinks.push(n)}if(null!=n)for(const{sourceLinks:e,targetLinks:r}of t)e.sort(n),r.sort(n)}function T({nodes:t}){for(const e of t)e.value=void 0===e.fixedValue?Math.max(f(e.sourceLinks,w),f(e.targetLinks,w)):e.fixedValue}function V({nodes:t}){const e=t.length;let n=new Set(t),r=new Set,o=0;for(;n.size;){for(const t of n){t.depth=o;for(const{target:e}of t.sourceLinks)r.add(e)}if(++o>e)throw new Error("circular link");n=r,r=new Set}}function P({nodes:t}){const e=t.length;let n=new Set(t),r=new Set,o=0;for(;n.size;){for(const t of n){t.height=o;for(const{source:e}of t.targetLinks)r.add(e)}if(++o>e)throw new Error("circular link");n=r,r=new Set}}function E(n){const l=function({nodes:t}){const n=h(t,t=>t.depth)+1,o=(i-r-s)/(n-1),a=new Array(n);for(const e of t){const t=Math.max(0,Math.min(n-1,Math.floor(c.call(null,e,n))));e.layer=t,e.x0=r+t*o,e.x1=e.x0+s,a[t]?a[t].push(e):a[t]=[e]}if(e)for(const t of a)t.sort(e);return a}(n);t=Math.min(u,(a-o)/(h(l,t=>t.length)-1)),function(e){const n=d(e,e=>(a-o-(e.length-1)*t)/f(e,w));for(const r of e){let e=o;for(const o of r){o.y0=e,o.y1=e+o.value*n,e=o.y1+t;for(const t of o.sourceLinks)t.width=t.value*n}e=(a-e+t)/(r.length+1);for(let t=0;t0))continue;let o=(e/r-t.y0)*n;t.y0+=o,t.y1+=o,F(t)}void 0===e&&i.sort(x),B(i,r)}}function N(t,n,r){for(let o=t.length-2;o>=0;--o){const i=t[o];for(const t of i){let e=0,r=0;for(const{target:n,value:o}of t.sourceLinks){let i=o*(n.layer-t.layer);e+=I(t,n)*i,r+=i}if(!(r>0))continue;let o=(e/r-t.y0)*n;t.y0+=o,t.y1+=o,F(t)}void 0===e&&i.sort(x),B(i,r)}}function B(e,n){const r=e.length>>1,i=e[r];z(e,i.y0-t,r-1,n),H(e,i.y1+t,r+1,n),z(e,a,e.length-1,n),H(e,o,0,n)}function H(e,n,r,o){for(;r1e-6&&(i.y0+=a,i.y1+=a),n=i.y1+t}}function z(e,n,r,o){for(;r>=0;--r){const i=e[r],a=(i.y1-n)*o;a>1e-6&&(i.y0-=a,i.y1-=a),n=i.y0-t}}function F({sourceLinks:t,targetLinks:e}){if(void 0===n){for(const{source:{sourceLinks:t}}of e)t.sort(b);for(const{target:{targetLinks:e}}of t)e.sort(m)}}function J(t){if(void 0===n)for(const{sourceLinks:e,targetLinks:n}of t)e.sort(b),n.sort(m)}function G(e,n){let r=e.y0-(e.sourceLinks.length-1)*t/2;for(const{target:o,width:i}of e.sourceLinks){if(o===n)break;r+=i+t}for(const{source:t,width:o}of n.targetLinks){if(t===e)break;r-=o}return r}function I(e,n){let r=n.y0-(n.targetLinks.length-1)*t/2;for(const{source:o,width:i}of n.targetLinks){if(o===e)break;r+=i+t}for(const{target:t,width:o}of e.sourceLinks){if(t===n)break;r-=o}return r}return v.update=function(t){return j(t),t},v.nodeId=function(t){return arguments.length?(l="function"==typeof t?t:k(t),v):l},v.nodeAlign=function(t){return arguments.length?(c="function"==typeof t?t:k(t),v):c},v.nodeSort=function(t){return arguments.length?(e=t,v):e},v.nodeWidth=function(t){return arguments.length?(s=+t,v):s},v.nodePadding=function(e){return arguments.length?(u=t=+e,v):u},v.nodes=function(t){return arguments.length?(y="function"==typeof t?t:k(t),v):y},v.links=function(t){return arguments.length?(g="function"==typeof t?t:k(t),v):g},v.linkSort=function(t){return arguments.length?(n=t,v):n},v.size=function(t){return arguments.length?(r=o=0,i=+t[0],a=+t[1],v):[i-r,a-o]},v.extent=function(t){return arguments.length?(r=+t[0][0],i=+t[1][0],o=+t[0][1],a=+t[1][1],v):[[r,o],[i,a]]},v.iterations=function(t){return arguments.length?(p=+t,v):p},v}var T=Math.PI,V=2*T,P=V-1e-6;function E(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function C(){return new E}E.prototype=C.prototype={constructor:E,moveTo:function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},quadraticCurveTo:function(t,e,n,r){this._+="Q"+ +t+","+ +e+","+(this._x1=+n)+","+(this._y1=+r)},bezierCurveTo:function(t,e,n,r,o,i){this._+="C"+ +t+","+ +e+","+ +n+","+ +r+","+(this._x1=+o)+","+(this._y1=+i)},arcTo:function(t,e,n,r,o){t=+t,e=+e,n=+n,r=+r,o=+o;var i=this._x1,a=this._y1,s=n-t,u=r-e,l=i-t,c=a-e,f=l*l+c*c;if(o<0)throw new Error("negative radius: "+o);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(f>1e-6)if(Math.abs(c*s-u*l)>1e-6&&o){var h=n-i,d=r-a,y=s*s+u*u,g=h*h+d*d,p=Math.sqrt(y),_=Math.sqrt(f),v=o*Math.tan((T-Math.acos((y+f-g)/(2*p*_)))/2),k=v/_,m=v/p;Math.abs(k-1)>1e-6&&(this._+="L"+(t+k*l)+","+(e+k*c)),this._+="A"+o+","+o+",0,0,"+ +(c*h>l*d)+","+(this._x1=t+m*s)+","+(this._y1=e+m*u)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,r,o,i){t=+t,e=+e,i=!!i;var a=(n=+n)*Math.cos(r),s=n*Math.sin(r),u=t+a,l=e+s,c=1^i,f=i?r-o:o-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+u+","+l:(Math.abs(this._x1-u)>1e-6||Math.abs(this._y1-l)>1e-6)&&(this._+="L"+u+","+l),n&&(f<0&&(f=f%V+V),f>P?this._+="A"+n+","+n+",0,1,"+c+","+(t-a)+","+(e-s)+"A"+n+","+n+",0,1,"+c+","+(this._x1=u)+","+(this._y1=l):f>1e-6&&(this._+="A"+n+","+n+",0,"+ +(f>=T)+","+c+","+(this._x1=t+n*Math.cos(o))+","+(this._y1=e+n*Math.sin(o))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var N=C,B=Array.prototype.slice,H=function(t){return function(){return t}};function z(t){return t[0]}function F(t){return t[1]}function J(t){return t.source}function G(t){return t.target}function I(t){var e=J,n=G,r=z,o=F,i=null;function a(){var a,s=B.call(arguments),u=e.apply(this,s),l=n.apply(this,s);if(i||(i=a=N()),t(i,+r.apply(this,(s[0]=u,s)),+o.apply(this,s),+r.apply(this,(s[0]=l,s)),+o.apply(this,s)),a)return i=null,a+""||null}return a.source=function(t){return arguments.length?(e=t,a):e},a.target=function(t){return arguments.length?(n=t,a):n},a.x=function(t){return arguments.length?(r="function"==typeof t?t:H(+t),a):r},a.y=function(t){return arguments.length?(o="function"==typeof t?t:H(+t),a):o},a.context=function(t){return arguments.length?(i=null==t?null:t,a):i},a}function D(t,e,n,r,o){t.moveTo(e,n),t.bezierCurveTo(e=(e+r)/2,n,e,o,r,o)}function R(t){return[t.source.x1,t.y0]}function W(t){return[t.target.x0,t.y1]}var q=function(){return I(D).source(R).target(W)};function U(t,e){for(var n=0;n0&&this._data.links.length>0}},{key:"_setLinkGradient",value:function(){var t=this,e=this._svgLink.append("linearGradient").attr("id",(function(t){return t.uid="link-".concat(t.index,"-").concat(Math.random())})).attr("gradientUnits","userSpaceOnUse").attr("x1",(function(t){return t.source.x1})).attr("x2",(function(t){return t.target.x0}));e.append("stop").attr("offset","0%").attr("stop-color",(function(e){return t._color(e.source)})),e.append("stop").attr("offset","100%").attr("stop-color",(function(e){return t._color(e.target)}))}},{key:"_setLinkStroke",value:function(t){switch(this._edgeColor){case X:return"#aaa";case Y:return"url(#".concat(t.uid,")");case $:return this._color(t.source);case tt:return this._color(t.target);default:return}}},{key:"_showLinks",value:function(t){var e=[];[{linkType:"sourceLinks",nodeType:"target"},{linkType:"targetLinks",nodeType:"source"}].forEach((function(n){t[n.linkType].forEach((function(t){e.push(t[n.nodeType])}))})),this._gBound.selectAll(".sankey-node").style("opacity",(function(n){return t.name===n.name||e.find((function(t){return t.name===n.name}))?"1":"0.2"})),this._gBound.selectAll(".sankey-link").style("opacity",(function(e){return!e||e.source.name!==t.name&&e.target.name!==t.name?"0.2":"1"}))}},{key:"_showAll",value:function(){this._gBound.selectAll(".sankey-node").style("opacity","1"),this._gBound.selectAll(".sankey-link").style("opacity","1")}},{key:"_formatValue",value:function(t){return c.format(".2~f")(t)}},{key:"_formatPercent",value:function(t){return c.format(".2~%")(t)}},{key:"_formatThousand",value:function(t){return c.format(".3~s")(t)}},{key:"_labelNodeValue",value:function(t){var e=this._nodes.filter((function(e){return e.depth===t.depth})),n=c.sum(e,(function(t){return t.value})),r=this._formatThousand(t.value),o=this._formatPercent(t.value/n),i="";switch(this._displayValues){case Z:i="".concat(r);break;case Q:i="".concat(o);break;case K:i="".concat(o," - ").concat(r)}return i}},{key:"_renderSVG",value:function(){var t=this;this._container.style("background-color",this._background),this._gBound=this._container.append("g").attr("transform","translate(".concat(this._marginLeft,", ").concat(this._marginTop,")")),this._svgNode=this._gBound.append("g").attr("stroke","#000").selectAll(".sankey-node").data(this._nodes,(function(t){return t.name})).join("rect").attr("class","sankey-node").attr("id",(function(t){return t.name})).attr("x",(function(t){return t.x0})).attr("y",(function(t){return t.y0})).attr("rx",2).attr("ry",2).attr("height",(function(t){return t.y1-t.y0})).attr("width",(function(t){return t.x1-t.x0})).attr("stroke",(function(e){var n=JSON.parse(t._colorArray);return Object.keys(n).includes(e.name)?n[e.name]:"rgba(148, 153, 168, 1)"})).attr("fill",(function(e){var n=JSON.parse(t._colorArray);return Object.keys(n).includes(e.name)?n[e.name]:"rgba(148, 153, 168, 1)"})).on("mouseover",(function(e){return t._highlightOnHover&&t._showLinks(e)})).on("mouseout",(function(e){return t._highlightOnHover&&t._showAll()})),this._svgLink=this._gBound.append("g").attr("fill","none").attr("stroke-opacity",.3).selectAll("g").data(this._links,(function(t){return"".concat(t.source.name,"-").concat(t.target.name)})).join("g").style("mix-blend-mode","multiply"),"path"===this._edgeColor&&this._setLinkGradient(),this._svgLink.append("path").attr("class","sankey-link").attr("d",q()).attr("stroke","rgba(182, 185, 196, 1)").attr("stroke-width",(function(t){return Math.max(1,t.width)})),this._gBound.append("g").attr("font-family","sans-serif").attr("font-size",10).selectAll("text").data(this._nodes).join("text").attr("x",(function(t){return t.x0+8})).attr("y",(function(t){return(t.y1+t.y0)/2})).attr("dy","0.35em").text((function(t){return t.name})),this._gBound.append("g").attr("font-family","sans-serif").attr("font-size",10).selectAll("text").data(this._nodes).join("text").attr("x",(function(t){return t.x0+8})).attr("font-size",14).attr("font-weight","700").attr("y",(function(t){return(t.y1+t.y0)/2+16})).attr("dy","0.35em").text((function(e){return t._labelNodeValue(e)})),this._svgNode.append("title").text((function(e){return"".concat(e.name,"\n").concat(t._formatValue(e.value))})),this._svgLink.append("title").text((function(e){return"".concat(e.source.name," → ").concat(e.target.name,"\n").concat(t._formatValue(e.value))}))}},{key:"data",value:function(t){return arguments.length?(this._data=t,this):this._data}},{key:"width",value:function(t){return arguments.length?(this._width=+t,this):this._width}},{key:"height",value:function(t){return arguments.length?(this._height=+t,this):this._height}},{key:"align",value:function(t){return arguments.length?(this._sankeyAlignType=t,this):this._sankeyAlignType}},{key:"colorScheme",value:function(t){return arguments.length?(this._colorScheme=t,this):this._colorScheme}},{key:"colorArray",value:function(t){return arguments.length?(this._colorArray=t,this):this._colorArray}},{key:"edgeColor",value:function(t){return arguments.length?(this._edgeColor=t,this):this._edgeColor}},{key:"displayValues",value:function(t){return arguments.length?(this._displayValues=t,this):this._displayValues}},{key:"highlightOnHover",value:function(t){return arguments.length?(this._highlightOnHover=t,this):this._highlightOnHover}},{key:"render",value:function(){return this._validate()&&(this._init(),this._renderSVG()),this}}])&&U(e.prototype,n),o&&U(e,o),t}(),nt=n(3),rt=function(t){var e=t.message;return l.a.createElement("p",{style:ot},l.a.createElement("div",{style:it},l.a.createElement(nt.Icon,{name:"exclamation-triangle"}),l.a.createElement("div",{style:at},e)))},ot={height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},it={padding:"15px 20px",marginBottom:"4px",position:"relative",color:"rgb(255, 255, 255)",textShadow:"rgb(0 0 0 / 20%) 0px 1px 0px",borderRadius:"3px",display:"flex",flexDirection:"row",alignItems:"center",background:"linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))"},at={marginLeft:10},st=function(t){void 0===t&&(t=!0);if(!t)return{warn:function(){for(var t=[],e=0;e 0) && !(r = i.next()).done; ) a.push(r.value); + } catch (t) { + o = { error: t }; + } finally { + try { + r && !r.done && (n = i.return) && n.call(i); + } finally { + if (o) throw o.error; + } + } + return a; + } + var u = n(0), + l = n.n(u), + c = n(1); + function f(t, e) { + let n = 0; + if (void 0 === e) for (let e of t) (e = +e) && (n += e); + else { + let r = -1; + for (let o of t) (o = +e(o, ++r, t)) && (n += o); + } + return n; + } + function h(t, e) { + let n; + if (void 0 === e) for (const e of t) null != e && (n < e || (void 0 === n && e >= e)) && (n = e); + else { + let r = -1; + for (let o of t) null != (o = e(o, ++r, t)) && (n < o || (void 0 === n && o >= o)) && (n = o); + } + return n; + } + function d(t, e) { + let n; + if (void 0 === e) for (const e of t) null != e && (n > e || (void 0 === n && e >= e)) && (n = e); + else { + let r = -1; + for (let o of t) null != (o = e(o, ++r, t)) && (n > o || (void 0 === n && o >= o)) && (n = o); + } + return n; + } + function y(t) { + return t.target.depth; + } + function g(t) { + return t.depth; + } + function p(t, e) { + return e - 1 - t.height; + } + function _(t, e) { + return t.sourceLinks.length ? t.depth : e - 1; + } + function v(t) { + return t.targetLinks.length ? t.depth : t.sourceLinks.length ? d(t.sourceLinks, y) - 1 : 0; + } + function k(t) { + return function () { + return t; + }; + } + function m(t, e) { + return x(t.source, e.source) || t.index - e.index; + } + function b(t, e) { + return x(t.target, e.target) || t.index - e.index; + } + function x(t, e) { + return t.y0 - e.y0; + } + function w(t) { + return t.value; + } + function S(t) { + return t.index; + } + function L(t) { + return t.nodes; + } + function A(t) { + return t.links; + } + function O(t, e) { + const n = t.get(e); + if (!n) throw new Error('missing: ' + e); + return n; + } + function j({ nodes: t }) { + for (const e of t) { + let t = e.y0, + n = t; + for (const n of e.sourceLinks) (n.y0 = t + n.width / 2), (t += n.width); + for (const t of e.targetLinks) (t.y1 = n + t.width / 2), (n += t.width); + } + } + function M() { + let t, + e, + n, + r = 0, + o = 0, + i = 1, + a = 1, + s = 24, + u = 8, + l = S, + c = _, + y = L, + g = A, + p = 6; + function v() { + const t = { nodes: y.apply(null, arguments), links: g.apply(null, arguments) }; + return M(t), T(t), V(t), P(t), E(t), j(t), t; + } + function M({ nodes: t, links: e }) { + for (const [e, n] of t.entries()) (n.index = e), (n.sourceLinks = []), (n.targetLinks = []); + const r = new Map(t.map((e, n) => [l(e, n, t), e])); + for (const [t, n] of e.entries()) { + n.index = t; + let { source: e, target: o } = n; + 'object' != typeof e && (e = n.source = O(r, e)), + 'object' != typeof o && (o = n.target = O(r, o)), + e.sourceLinks.push(n), + o.targetLinks.push(n); + } + if (null != n) for (const { sourceLinks: e, targetLinks: r } of t) e.sort(n), r.sort(n); + } + function T({ nodes: t }) { + for (const e of t) + e.value = void 0 === e.fixedValue ? Math.max(f(e.sourceLinks, w), f(e.targetLinks, w)) : e.fixedValue; + } + function V({ nodes: t }) { + const e = t.length; + let n = new Set(t), + r = new Set(), + o = 0; + for (; n.size; ) { + for (const t of n) { + t.depth = o; + for (const { target: e } of t.sourceLinks) r.add(e); + } + if (++o > e) throw new Error('circular link'); + (n = r), (r = new Set()); + } + } + function P({ nodes: t }) { + const e = t.length; + let n = new Set(t), + r = new Set(), + o = 0; + for (; n.size; ) { + for (const t of n) { + t.height = o; + for (const { source: e } of t.targetLinks) r.add(e); + } + if (++o > e) throw new Error('circular link'); + (n = r), (r = new Set()); + } + } + function E(n) { + const l = (function ({ nodes: t }) { + const n = h(t, (t) => t.depth) + 1, + o = (i - r - s) / (n - 1), + a = new Array(n); + for (const e of t) { + const t = Math.max(0, Math.min(n - 1, Math.floor(c.call(null, e, n)))); + (e.layer = t), (e.x0 = r + t * o), (e.x1 = e.x0 + s), a[t] ? a[t].push(e) : (a[t] = [e]); + } + if (e) for (const t of a) t.sort(e); + return a; + })(n); + (t = Math.min(u, (a - o) / (h(l, (t) => t.length) - 1))), + (function (e) { + const n = d(e, (e) => (a - o - (e.length - 1) * t) / f(e, w)); + for (const r of e) { + let e = o; + for (const o of r) { + (o.y0 = e), (o.y1 = e + o.value * n), (e = o.y1 + t); + for (const t of o.sourceLinks) t.width = t.value * n; + } + e = (a - e + t) / (r.length + 1); + for (let t = 0; t < r.length; ++t) { + const n = r[t]; + (n.y0 += e * (t + 1)), (n.y1 += e * (t + 1)); + } + J(r); + } + })(l); + for (let t = 0; t < p; ++t) { + const e = Math.pow(0.99, t), + n = Math.max(1 - e, (t + 1) / p); + N(l, e, n), C(l, e, n); + } + } + function C(t, n, r) { + for (let o = 1, i = t.length; o < i; ++o) { + const i = t[o]; + for (const t of i) { + let e = 0, + r = 0; + for (const { source: n, value: o } of t.targetLinks) { + let i = o * (t.layer - n.layer); + (e += G(n, t) * i), (r += i); + } + if (!(r > 0)) continue; + let o = (e / r - t.y0) * n; + (t.y0 += o), (t.y1 += o), F(t); + } + void 0 === e && i.sort(x), B(i, r); + } + } + function N(t, n, r) { + for (let o = t.length - 2; o >= 0; --o) { + const i = t[o]; + for (const t of i) { + let e = 0, + r = 0; + for (const { target: n, value: o } of t.sourceLinks) { + let i = o * (n.layer - t.layer); + (e += I(t, n) * i), (r += i); + } + if (!(r > 0)) continue; + let o = (e / r - t.y0) * n; + (t.y0 += o), (t.y1 += o), F(t); + } + void 0 === e && i.sort(x), B(i, r); + } + } + function B(e, n) { + const r = e.length >> 1, + i = e[r]; + z(e, i.y0 - t, r - 1, n), H(e, i.y1 + t, r + 1, n), z(e, a, e.length - 1, n), H(e, o, 0, n); + } + function H(e, n, r, o) { + for (; r < e.length; ++r) { + const i = e[r], + a = (n - i.y0) * o; + a > 1e-6 && ((i.y0 += a), (i.y1 += a)), (n = i.y1 + t); + } + } + function z(e, n, r, o) { + for (; r >= 0; --r) { + const i = e[r], + a = (i.y1 - n) * o; + a > 1e-6 && ((i.y0 -= a), (i.y1 -= a)), (n = i.y0 - t); + } + } + function F({ sourceLinks: t, targetLinks: e }) { + if (void 0 === n) { + for (const { + source: { sourceLinks: t }, + } of e) + t.sort(b); + for (const { + target: { targetLinks: e }, + } of t) + e.sort(m); + } + } + function J(t) { + if (void 0 === n) for (const { sourceLinks: e, targetLinks: n } of t) e.sort(b), n.sort(m); + } + function G(e, n) { + let r = e.y0 - ((e.sourceLinks.length - 1) * t) / 2; + for (const { target: o, width: i } of e.sourceLinks) { + if (o === n) break; + r += i + t; + } + for (const { source: t, width: o } of n.targetLinks) { + if (t === e) break; + r -= o; + } + return r; + } + function I(e, n) { + let r = n.y0 - ((n.targetLinks.length - 1) * t) / 2; + for (const { source: o, width: i } of n.targetLinks) { + if (o === e) break; + r += i + t; + } + for (const { target: t, width: o } of e.sourceLinks) { + if (t === n) break; + r -= o; + } + return r; + } + return ( + (v.update = function (t) { + return j(t), t; + }), + (v.nodeId = function (t) { + return arguments.length ? ((l = 'function' == typeof t ? t : k(t)), v) : l; + }), + (v.nodeAlign = function (t) { + return arguments.length ? ((c = 'function' == typeof t ? t : k(t)), v) : c; + }), + (v.nodeSort = function (t) { + return arguments.length ? ((e = t), v) : e; + }), + (v.nodeWidth = function (t) { + return arguments.length ? ((s = +t), v) : s; + }), + (v.nodePadding = function (e) { + return arguments.length ? ((u = t = +e), v) : u; + }), + (v.nodes = function (t) { + return arguments.length ? ((y = 'function' == typeof t ? t : k(t)), v) : y; + }), + (v.links = function (t) { + return arguments.length ? ((g = 'function' == typeof t ? t : k(t)), v) : g; + }), + (v.linkSort = function (t) { + return arguments.length ? ((n = t), v) : n; + }), + (v.size = function (t) { + return arguments.length ? ((r = o = 0), (i = +t[0]), (a = +t[1]), v) : [i - r, a - o]; + }), + (v.extent = function (t) { + return arguments.length + ? ((r = +t[0][0]), (i = +t[1][0]), (o = +t[0][1]), (a = +t[1][1]), v) + : [ + [r, o], + [i, a], + ]; + }), + (v.iterations = function (t) { + return arguments.length ? ((p = +t), v) : p; + }), + v + ); + } + var T = Math.PI, + V = 2 * T, + P = V - 1e-6; + function E() { + (this._x0 = this._y0 = this._x1 = this._y1 = null), (this._ = ''); + } + function C() { + return new E(); + } + E.prototype = C.prototype = { + constructor: E, + moveTo: function (t, e) { + this._ += 'M' + (this._x0 = this._x1 = +t) + ',' + (this._y0 = this._y1 = +e); + }, + closePath: function () { + null !== this._x1 && ((this._x1 = this._x0), (this._y1 = this._y0), (this._ += 'Z')); + }, + lineTo: function (t, e) { + this._ += 'L' + (this._x1 = +t) + ',' + (this._y1 = +e); + }, + quadraticCurveTo: function (t, e, n, r) { + this._ += 'Q' + +t + ',' + +e + ',' + (this._x1 = +n) + ',' + (this._y1 = +r); + }, + bezierCurveTo: function (t, e, n, r, o, i) { + this._ += 'C' + +t + ',' + +e + ',' + +n + ',' + +r + ',' + (this._x1 = +o) + ',' + (this._y1 = +i); + }, + arcTo: function (t, e, n, r, o) { + (t = +t), (e = +e), (n = +n), (r = +r), (o = +o); + var i = this._x1, + a = this._y1, + s = n - t, + u = r - e, + l = i - t, + c = a - e, + f = l * l + c * c; + if (o < 0) throw new Error('negative radius: ' + o); + if (null === this._x1) this._ += 'M' + (this._x1 = t) + ',' + (this._y1 = e); + else if (f > 1e-6) + if (Math.abs(c * s - u * l) > 1e-6 && o) { + var h = n - i, + d = r - a, + y = s * s + u * u, + g = h * h + d * d, + p = Math.sqrt(y), + _ = Math.sqrt(f), + v = o * Math.tan((T - Math.acos((y + f - g) / (2 * p * _))) / 2), + k = v / _, + m = v / p; + Math.abs(k - 1) > 1e-6 && (this._ += 'L' + (t + k * l) + ',' + (e + k * c)), + (this._ += + 'A' + + o + + ',' + + o + + ',0,0,' + + +(c * h > l * d) + + ',' + + (this._x1 = t + m * s) + + ',' + + (this._y1 = e + m * u)); + } else this._ += 'L' + (this._x1 = t) + ',' + (this._y1 = e); + else; + }, + arc: function (t, e, n, r, o, i) { + (t = +t), (e = +e), (i = !!i); + var a = (n = +n) * Math.cos(r), + s = n * Math.sin(r), + u = t + a, + l = e + s, + c = 1 ^ i, + f = i ? r - o : o - r; + if (n < 0) throw new Error('negative radius: ' + n); + null === this._x1 + ? (this._ += 'M' + u + ',' + l) + : (Math.abs(this._x1 - u) > 1e-6 || Math.abs(this._y1 - l) > 1e-6) && (this._ += 'L' + u + ',' + l), + n && + (f < 0 && (f = (f % V) + V), + f > P + ? (this._ += + 'A' + + n + + ',' + + n + + ',0,1,' + + c + + ',' + + (t - a) + + ',' + + (e - s) + + 'A' + + n + + ',' + + n + + ',0,1,' + + c + + ',' + + (this._x1 = u) + + ',' + + (this._y1 = l)) + : f > 1e-6 && + (this._ += + 'A' + + n + + ',' + + n + + ',0,' + + +(f >= T) + + ',' + + c + + ',' + + (this._x1 = t + n * Math.cos(o)) + + ',' + + (this._y1 = e + n * Math.sin(o)))); + }, + rect: function (t, e, n, r) { + this._ += + 'M' + (this._x0 = this._x1 = +t) + ',' + (this._y0 = this._y1 = +e) + 'h' + +n + 'v' + +r + 'h' + -n + 'Z'; + }, + toString: function () { + return this._; + }, + }; + var N = C, + B = Array.prototype.slice, + H = function (t) { + return function () { + return t; + }; + }; + function z(t) { + return t[0]; + } + function F(t) { + return t[1]; + } + function J(t) { + return t.source; + } + function G(t) { + return t.target; + } + function I(t) { + var e = J, + n = G, + r = z, + o = F, + i = null; + function a() { + var a, + s = B.call(arguments), + u = e.apply(this, s), + l = n.apply(this, s); + if ( + (i || (i = a = N()), + t( + i, + +r.apply(this, ((s[0] = u), s)), + +o.apply(this, s), + +r.apply(this, ((s[0] = l), s)), + +o.apply(this, s) + ), + a) + ) + return (i = null), a + '' || null; + } + return ( + (a.source = function (t) { + return arguments.length ? ((e = t), a) : e; + }), + (a.target = function (t) { + return arguments.length ? ((n = t), a) : n; + }), + (a.x = function (t) { + return arguments.length ? ((r = 'function' == typeof t ? t : H(+t)), a) : r; + }), + (a.y = function (t) { + return arguments.length ? ((o = 'function' == typeof t ? t : H(+t)), a) : o; + }), + (a.context = function (t) { + return arguments.length ? ((i = null == t ? null : t), a) : i; + }), + a + ); + } + function D(t, e, n, r, o) { + t.moveTo(e, n), t.bezierCurveTo((e = (e + r) / 2), n, e, o, r, o); + } + function R(t) { + return [t.source.x1, t.y0]; + } + function W(t) { + return [t.target.x0, t.y1]; + } + var q = function () { + return I(D).source(R).target(W); + }; + function U(t, e) { + for (var n = 0; n < e.length; n++) { + var r = e[n]; + (r.enumerable = r.enumerable || !1), + (r.configurable = !0), + 'value' in r && (r.writable = !0), + Object.defineProperty(t, r.key, r); + } + } + var Z = 'total', + Q = 'percentage', + K = 'both', + X = 'none', + Y = 'path', + $ = 'input', + tt = 'output', + et = (function () { + function t(e, n) { + !(function (t, e) { + if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); + })(this, t), + (this._svg = e), + (this._container = n || e), + (this._gBound = null), + (this._data = null), + (this._nodes = null), + (this._links = null), + (this._width = 0), + (this._height = 0), + (this._boundedWidth = 0), + (this._boundedHeight = 0), + (this._marginTop = 20), + (this._marginRight = 20), + (this._marginBottom = 20), + (this._marginLeft = 20), + (this._background = 'rgba(0, 0, 0, 0)'), + (this._edgeColor = 'path'), + (this._colorScheme = 'Tableau10'), + (this._colorScale = null), + (this._colorArray = ''), + (this._sankeyAlignType = 'Justify'), + (this._sankeyAlign = null), + (this._sankeyGenerator = null), + (this._sankeyNodeWith = 110), + (this._sankeyNodePadding = 20), + (this._svgNode = null), + (this._svgLink = null), + (this._displayValues = 'none'), + (this._highlightOnHover = !1); + } + var e, n, o; + return ( + (e = t), + (n = [ + { + key: '_init', + value: function () { + this._setBoundDimensions(), this._setColorScale(), this._configureSankey(), this._calculateSankey(); + }, + }, + { + key: '_setBoundDimensions', + value: function () { + (this._boundedWidth = this._width - this._marginLeft - this._marginRight), + (this._boundedHeight = this._height - this._marginTop - this._marginBottom); + }, + }, + { + key: '_setColorScale', + value: function () { + this._colorScale = c.scaleOrdinal(c['scheme'.concat(this._colorScheme)]); + }, + }, + { + key: '_color', + value: function (t) { + return this._colorScale(t.name); + }, + }, + { + key: '_configureSankey', + value: function () { + (this._sankeyAlign = r['sankey'.concat(this._sankeyAlignType)]), + (this._sankeyGenerator = M() + .nodeId(function (t) { + return t.name; + }) + .nodeAlign(this._sankeyAlign) + .nodeWidth(this._sankeyNodeWith) + .nodePadding(this._sankeyNodePadding) + .extent([ + [0, 0], + [this._boundedWidth, this._boundedHeight], + ])); + }, + }, + { + key: '_calculateSankey', + value: function () { + var t = this._sankeyGenerator({ + nodes: this._data.nodes.map(function (t) { + return Object.assign({}, t); + }), + links: this._data.links.map(function (t) { + return Object.assign({}, t); + }), + }); + (this._nodes = t.nodes.filter(function (t) { + return 0 !== t.value; + })), + (this._links = t.links.filter(function (t) { + return 0 !== t.value; + })); + }, + }, + { + key: '_validate', + value: function () { + return ( + this._data && + this._data.nodes && + this._data.links && + this._data.nodes.length > 0 && + this._data.links.length > 0 + ); + }, + }, + { + key: '_setLinkGradient', + value: function () { + var t = this, + e = this._svgLink + .append('linearGradient') + .attr('id', function (t) { + return (t.uid = 'link-'.concat(t.index, '-').concat(Math.random())); + }) + .attr('gradientUnits', 'userSpaceOnUse') + .attr('x1', function (t) { + return t.source.x1; + }) + .attr('x2', function (t) { + return t.target.x0; + }); + e + .append('stop') + .attr('offset', '0%') + .attr('stop-color', function (e) { + return t._color(e.source); + }), + e + .append('stop') + .attr('offset', '100%') + .attr('stop-color', function (e) { + return t._color(e.target); + }); + }, + }, + { + key: '_setLinkStroke', + value: function (t) { + switch (this._edgeColor) { + case X: + return '#aaa'; + case Y: + return 'url(#'.concat(t.uid, ')'); + case $: + return this._color(t.source); + case tt: + return this._color(t.target); + default: + return; + } + }, + }, + { + key: '_showLinks', + value: function (t) { + var e = []; + [ + { linkType: 'sourceLinks', nodeType: 'target' }, + { linkType: 'targetLinks', nodeType: 'source' }, + ].forEach(function (n) { + t[n.linkType].forEach(function (t) { + e.push(t[n.nodeType]); + }); + }), + this._gBound.selectAll('.sankey-node').style('opacity', function (n) { + return t.name === n.name || + e.find(function (t) { + return t.name === n.name; + }) + ? '1' + : '0.2'; + }), + this._gBound.selectAll('.sankey-link').style('opacity', function (e) { + return !e || (e.source.name !== t.name && e.target.name !== t.name) ? '0.2' : '1'; + }); + }, + }, + { + key: '_showAll', + value: function () { + this._gBound.selectAll('.sankey-node').style('opacity', '1'), + this._gBound.selectAll('.sankey-link').style('opacity', '1'); + }, + }, + { + key: '_formatValue', + value: function (t) { + return c.format('.2~f')(t); + }, + }, + { + key: '_formatPercent', + value: function (t) { + return c.format('.2~%')(t); + }, + }, + { + key: '_formatThousand', + value: function (t) { + return c.format('.3~s')(t); + }, + }, + { + key: '_labelNodeValue', + value: function (t) { + var e = this._nodes.filter(function (e) { + return e.depth === t.depth; + }), + n = c.sum(e, function (t) { + return t.value; + }), + r = this._formatThousand(t.value), + o = this._formatPercent(t.value / n), + i = ''; + switch (this._displayValues) { + case Z: + i = ''.concat(r); + break; + case Q: + i = ''.concat(o); + break; + case K: + i = ''.concat(o, ' - ').concat(r); + } + return i; + }, + }, + { + key: '_renderSVG', + value: function () { + var t = this; + this._container.style('background-color', this._background), + (this._gBound = this._container + .append('g') + .attr('transform', 'translate('.concat(this._marginLeft, ', ').concat(this._marginTop, ')'))), + (this._svgNode = this._gBound + .append('g') + .attr('stroke', '#000') + .selectAll('.sankey-node') + .data(this._nodes, function (t) { + return t.name; + }) + .join('rect') + .attr('class', 'sankey-node') + .attr('id', function (t) { + return t.name; + }) + .attr('x', function (t) { + return t.x0; + }) + .attr('y', function (t) { + return t.y0; + }) + .attr('rx', 2) + .attr('ry', 2) + .attr('height', function (t) { + return t.y1 - t.y0; + }) + .attr('width', function (t) { + return t.x1 - t.x0; + }) + .attr('stroke', function (e) { + var n = JSON.parse(t._colorArray); + return Object.keys(n).includes(e.name) ? n[e.name] : 'rgba(148, 153, 168, 1)'; + }) + .attr('fill', function (e) { + var n = JSON.parse(t._colorArray); + return Object.keys(n).includes(e.name) ? n[e.name] : 'rgba(148, 153, 168, 1)'; + }) + .on('mouseover', function (e) { + var n; + return ( + t._highlightOnHover && + t._showLinks(null === (n = e.target) || void 0 === n ? void 0 : n.__data__) + ); + }) + .on('mouseout', function (e) { + return t._highlightOnHover && t._showAll(); + })), + (this._svgLink = this._gBound + .append('g') + .attr('fill', 'none') + .attr('stroke-opacity', 0.3) + .selectAll('g') + .data(this._links, function (t) { + return ''.concat(t.source.name, '-').concat(t.target.name); + }) + .join('g') + .style('mix-blend-mode', 'multiply')), + 'path' === this._edgeColor && this._setLinkGradient(), + this._svgLink + .append('path') + .attr('class', 'sankey-link') + .attr('d', q()) + .attr('stroke', 'rgba(182, 185, 196, 1)') + .attr('stroke-width', function (t) { + return Math.max(1, t.width); + }), + this._gBound + .append('g') + .attr('font-family', 'sans-serif') + .attr('font-size', 10) + .selectAll('text') + .data(this._nodes) + .join('text') + .attr('x', function (t) { + return t.x0 + 8; + }) + .attr('y', function (t) { + return (t.y1 + t.y0) / 2; + }) + .attr('dy', '0.35em') + .text(function (t) { + return t.name; + }), + this._gBound + .append('g') + .attr('font-family', 'sans-serif') + .attr('font-size', 10) + .selectAll('text') + .data(this._nodes) + .join('text') + .attr('x', function (t) { + return t.x0 + 8; + }) + .attr('font-size', 14) + .attr('font-weight', '700') + .attr('y', function (t) { + return (t.y1 + t.y0) / 2 + 16; + }) + .attr('dy', '0.35em') + .text(function (e) { + return t._labelNodeValue(e); + }), + this._svgNode.append('title').text(function (e) { + return ''.concat(e.name, '\n').concat(t._formatValue(e.value)); + }), + this._svgLink.append('title').text(function (e) { + return '' + .concat(e.source.name, ' → ') + .concat(e.target.name, '\n') + .concat(t._formatValue(e.value)); + }); + }, + }, + { + key: 'data', + value: function (t) { + return arguments.length ? ((this._data = t), this) : this._data; + }, + }, + { + key: 'width', + value: function (t) { + return arguments.length ? ((this._width = +t), this) : this._width; + }, + }, + { + key: 'height', + value: function (t) { + return arguments.length ? ((this._height = +t), this) : this._height; + }, + }, + { + key: 'align', + value: function (t) { + return arguments.length ? ((this._sankeyAlignType = t), this) : this._sankeyAlignType; + }, + }, + { + key: 'colorScheme', + value: function (t) { + return arguments.length ? ((this._colorScheme = t), this) : this._colorScheme; + }, + }, + { + key: 'colorArray', + value: function (t) { + return arguments.length ? ((this._colorArray = t), this) : this._colorArray; + }, + }, + { + key: 'edgeColor', + value: function (t) { + return arguments.length ? ((this._edgeColor = t), this) : this._edgeColor; + }, + }, + { + key: 'displayValues', + value: function (t) { + return arguments.length ? ((this._displayValues = t), this) : this._displayValues; + }, + }, + { + key: 'highlightOnHover', + value: function (t) { + return arguments.length ? ((this._highlightOnHover = t), this) : this._highlightOnHover; + }, + }, + { + key: 'render', + value: function () { + return this._validate() && (this._init(), this._renderSVG()), this; + }, + }, + ]) && U(e.prototype, n), + o && U(e, o), + t + ); + })(), + nt = n(3), + rt = function (t) { + var e = t.message; + return l.a.createElement( + 'p', + { style: ot }, + l.a.createElement( + 'div', + { style: it }, + l.a.createElement(nt.Icon, { name: 'exclamation-triangle' }), + l.a.createElement('div', { style: at }, e) + ) + ); + }, + ot = { height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }, + it = { + padding: '15px 20px', + marginBottom: '4px', + position: 'relative', + color: 'rgb(255, 255, 255)', + textShadow: 'rgb(0 0 0 / 20%) 0px 1px 0px', + borderRadius: '3px', + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + background: 'linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))', + }, + at = { marginLeft: 10 }, + st = (function (t) { + void 0 === t && (t = !0); + if (!t) + return { + warn: function () { + for (var t = [], e = 0; e < arguments.length; e++) t[e] = arguments[e]; + }, + error: function () { + for (var t = [], e = 0; e < arguments.length; e++) t[e] = arguments[e]; + }, + log: function () { + for (var t = [], e = 0; e < arguments.length; e++) t[e] = arguments[e]; + }, + }; + return { warn: console.warn, error: console.error, log: console.log }; + })(); + var ut = function (t) { + var e = t.options, + n = t.data, + r = t.width, + o = t.height, + i = { source: 'source', target: 'target', value: 'value' }, + a = 'Required fields not present: ' + Object.keys(i).join(', '), + f = s(Object(u.useState)({ isError: !1, message: '' }), 2), + h = f[0], + d = f[1], + y = s(Object(u.useState)({ nodes: [], links: [] }), 2), + g = y[0], + p = y[1]; + Object(u.useEffect)( + function () { + n.error && st.warn('[FN] Sankey data error.', { data: n, error: n.error }), + n.error ? d({ isError: !0, message: n.error.message }) : p(_()); + }, + [n] + ); + var _ = function () { + var t = n.series[0], + e = t.fields.find(function (t) { + return t.name === i.source; + }), + r = t.fields.find(function (t) { + return t.name === i.target; + }), + o = t.fields.find(function (t) { + return t.name === i.value; + }), + s = null == e ? void 0 : e.values.toArray(), + u = null == r ? void 0 : r.values.toArray(), + l = null == o ? void 0 : o.values.toArray(); + if ( + (function (t, e, n) { + var r = !0; + if (!(t && e && n)) return d({ isError: !0, message: a }), !1; + var o = t.every(function (t) { + return 'string' == typeof t; + }), + i = e.every(function (t) { + return 'string' == typeof t; + }), + s = n.every(function (t) { + return 'number' == typeof t; + }); + return o && i && s + ? (d({}), r) + : (d({ + isError: !0, + message: + 'Fields should have the following types: source (string), target (string), value (numeric)', + }), + !1); + })(s, u, l) + ) { + var f = c.zip(s, u, l); + return { + nodes: Array.from(new Set(s.concat(u))).map(function (t) { + return { name: t }; + }), + links: f.map(function (t) { + return { source: t[0], target: t[1], value: +t[2].toFixed(2) }; + }), + }; + } + }, + v = function (t) { + var n = new et(t) + .width(r) + .height(o) + .align(e.align) + .edgeColor(e.edgeColor) + .colorScheme(e.colorScheme) + .displayValues(e.displayValues) + .highlightOnHover(e.highlightOnHover) + .colorArray(e.colorArray) + .data(g); + try { + n.render(); + } catch (t) { + st.warn('[FN] Sankey render error.', { renderError: t, graph: g }), + d({ isError: !0, message: t.message }); + } + }; + return h.isError + ? l.a.createElement(rt, { message: h.message }) + : l.a.createElement('svg', { + viewBox: '0 0 ' + r + ' ' + o, + ref: function (t) { + c.select(t).selectAll('*').remove(), c.select(t).call(v); + }, + }); + }; + function lt() { + return function (t) { + var e = t.series, + n = a(t, ['series']), + r = e.map(function (t) { + return Object(o.toDataFrame)( + i(i({}, t), { + fields: t.fields.map(function (t, e, n) { + var r, + a = ct.includes(t.name), + s = + t.values instanceof o.ArrayVector || + 'function' == typeof (null === (r = t.values) || void 0 === r ? void 0 : r.toArray), + u = Array.isArray(t.values); + if (!a || !t.values || (!u && !s)) return t; + var l = s ? t.values.toArray() : u ? t.values : null; + if (null === l) + return ( + st.warn('[FN] Failed to transform sankey data.', 'Values are not an array.'), + i(i({}, t), { values: new o.ArrayVector([]) }) + ); + var c = a + ? l + .map(function (t) { + return 'string' == typeof t ? t.split('|') : t; + })[0] + .map(function (t, e, n) { + return Number.isNaN(Number(t)) ? t : Number(t); + }) + : null; + try { + return i(i({}, t), { + type: ( + null == c + ? void 0 + : c.every(function (t) { + return 'number' == typeof t; + }) + ) + ? o.FieldType.number + : t.type, + values: c ? new o.ArrayVector(JSON.parse(JSON.stringify(c))) : l, + }); + } catch (e) { + return ( + st.warn('[FN] Failed to transform sankey data.', e instanceof Error ? e.message : String(e)), + i(i({}, t), { type: t.type, values: new o.ArrayVector([]) }) + ); + } + }), + }) + ); + }); + return i({ series: r }, n); + }; + } + var ct = ['source', 'target', 'value']; + n.d(e, 'plugin', function () { + return ft; + }); + var ft = new o.PanelPlugin(function (t) { + var e = t.data, + n = a(t, ['data']), + r = Object(u.useMemo)(lt, []), + o = Object(u.useMemo)( + function () { + return r(e); + }, + [r, e] + ); + return l.a.createElement(ut, i({}, i(i({}, n), { data: o }))); + }).setPanelOptions(function (t) { + return t + .addSelect({ + path: 'align', + name: 'Align', + defaultValue: 'Justify', + settings: { + options: [ + { value: 'Justify', label: 'Justify' }, + { value: 'Left', label: 'Left' }, + { value: 'Right', label: 'Right' }, + { value: 'Center', label: 'Center' }, + ], + }, + }) + .addTextInput({ path: 'colorArray', name: 'Color Object', defaultValue: '' }) + .addSelect({ + path: 'colorScheme', + name: 'Color', + defaultValue: 'Tableau10', + settings: { + options: [ + { value: 'Tableau10', label: 'Tableau10' }, + { value: 'Category10', label: 'Category10' }, + { value: 'Accent', label: 'Accent' }, + { value: 'Dark2', label: 'Dark2' }, + { value: 'Paired', label: 'Paired' }, + { value: 'Pastel1', label: 'Pastel1' }, + { value: 'Pastel2', label: 'Pastel2' }, + { value: 'Set1', label: 'Set1' }, + { value: 'Set2', label: 'Set2' }, + { value: 'Set3', label: 'Set3' }, + ], + }, + }) + .addSelect({ + path: 'edgeColor', + name: 'Edge Color', + defaultValue: 'path', + settings: { + options: [ + { value: 'path', label: 'input-output' }, + { value: 'input', label: 'input' }, + { value: 'output', label: 'output' }, + { value: 'none', label: 'none' }, + ], + }, + }) + .addSelect({ + path: 'displayValues', + name: 'Display Values', + defaultValue: 'none', + settings: { + options: [ + { value: 'total', label: 'Totals' }, + { value: 'percentage', label: 'Percentages' }, + { value: 'both', label: 'Both' }, + { value: 'none', label: 'None' }, + ], + }, + }) + .addBooleanSwitch({ + path: 'highlightOnHover', + name: 'Highlight connections on node hover', + defaultValue: !1, + }); + }); + }, + ]); +}); +//# sourceMappingURL=module.js.map diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/module.js.map b/public/app/plugins/panel/sankey-panel-0.5.0/module.js.map index 4339f9498f75a..8e5cb8a5eab5a 100644 --- a/public/app/plugins/panel/sankey-panel-0.5.0/module.js.map +++ b/public/app/plugins/panel/sankey-panel-0.5.0/module.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///external \"react\"","webpack:///external \"d3\"","webpack:///external \"@grafana/data\"","webpack:///external \"@grafana/ui\"","webpack:///../node_modules/tslib/tslib.es6.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/sum.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/max.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/min.js","webpack:///../node_modules/d3-sankey/src/align.js","webpack:///../node_modules/d3-sankey/src/constant.js","webpack:///../node_modules/d3-sankey/src/sankey.js","webpack:///../node_modules/d3-path/src/path.js","webpack:///../node_modules/d3-shape/src/array.js","webpack:///../node_modules/d3-shape/src/constant.js","webpack:///../node_modules/d3-shape/src/point.js","webpack:///../node_modules/d3-shape/src/link/index.js","webpack:///../node_modules/d3-sankey/src/sankeyLinkHorizontal.js","webpack:///./Sankey.js","webpack:///./Error.tsx","webpack:///./fn-logger.ts","webpack:///./SankeyPanel.tsx","webpack:///./transform-fn-data.ts","webpack:///./module.ts","webpack:///./SankeyPanelFn.tsx"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","__WEBPACK_EXTERNAL_MODULE__0__","__WEBPACK_EXTERNAL_MODULE__1__","__WEBPACK_EXTERNAL_MODULE__2__","__WEBPACK_EXTERNAL_MODULE__3__","__assign","assign","arguments","length","apply","this","__rest","e","indexOf","getOwnPropertySymbols","propertyIsEnumerable","__read","iterator","ar","next","done","push","error","sum","values","valueof","undefined","index","max","min","targetDepth","target","depth","left","node","right","height","justify","sourceLinks","center","targetLinks","constant","x","ascendingSourceBreadth","a","b","ascendingBreadth","source","ascendingTargetBreadth","y0","defaultId","defaultNodes","graph","nodes","defaultLinks","links","find","nodeById","id","Error","computeLinkBreadths","y1","link","width","py","sort","linkSort","x0","x1","dx","dy","align","iterations","sankey","computeNodeLinks","computeNodeValues","computeNodeDepths","computeNodeHeights","computeNodeBreadths","entries","Map","map","fixedValue","Math","current","Set","size","add","columns","kx","Array","floor","layer","column","computeNodeLayers","ky","y","reorderLinks","initializeNodeBreadths","alpha","pow","beta","relaxRightToLeft","relaxLeftToRight","w","v","targetTop","reorderNodeLinks","resolveCollisions","sourceTop","subject","resolveCollisionsBottomToTop","resolveCollisionsTopToBottom","update","nodeId","_","nodeAlign","nodeSort","nodeWidth","nodePadding","extent","pi","PI","tau","tauEpsilon","Path","_x0","_y0","_x1","_y1","path","constructor","moveTo","closePath","lineTo","quadraticCurveTo","bezierCurveTo","x2","y2","arcTo","x21","y21","x01","y01","l01_2","abs","x20","y20","l21_2","l20_2","l21","sqrt","l01","tan","acos","t01","t21","arc","a0","a1","ccw","cos","sin","cw","da","rect","h","toString","slice","linkSource","linkTarget","curve","context","buffer","argv","curveHorizontal","horizontalSource","horizontalTarget","DISPLAY_VALUES","EDGE_COLORS","Sankey","svg","container","_svg","_container","_gBound","_data","_nodes","_links","_width","_height","_boundedWidth","_boundedHeight","_marginTop","_marginRight","_marginBottom","_marginLeft","_background","_edgeColor","_colorScheme","_colorScale","_colorArray","_sankeyAlignType","_sankeyAlign","_sankeyGenerator","_sankeyNodeWith","_sankeyNodePadding","_svgNode","_svgLink","_displayValues","_highlightOnHover","_setBoundDimensions","_setColorScale","_configureSankey","_calculateSankey","d3","d3Sankey","sankeyData","filter","gradient","append","attr","uid","random","_color","currentNode","linkedNodes","linkType","nodeType","forEach","step","selectAll","style","linkedNode","percent","nodesAtDepth","totalAtDepth","nodeValue","_formatThousand","nodePercent","_formatPercent","label","data","join","colorArray","JSON","parse","keys","includes","on","_showLinks","_showAll","_setLinkGradient","text","_labelNodeValue","_formatValue","_validate","_init","_renderSVG","message","panelStyles","containerStyles","messageStyles","display","justifyContent","alignItems","padding","marginBottom","position","color","textShadow","borderRadius","flexDirection","background","marginLeft","logger","shouldLog","warn","log","console","fnLogger","options","CHART_REQUIRED_FIELDS","requiredFieldsMsg","isError","setError","setGraph","buildGraph","frame","series","sourceAccesor","fields","field","targetAccesor","valueAccesor","sources","toArray","targets","isValid","sourcesString","every","targetsString","valuesNumeric","validate","zip","from","concat","toFixed","chart","edgeColor","colorScheme","displayValues","highlightOnHover","render","renderError","viewBox","ref","remove","transformFnData","other","transformedSeries","__","isSankeyField","SANKEY_FIELD_NAMES","isArrayVector","isArray","parsedValues","split","Number","isNaN","type","number","stringify","err","String","props","transformFn","transformedData","setPanelOptions","builder","addSelect","defaultValue","settings","addTextInput","addBooleanSwitch"],"mappings":"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MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,QACP+P,MAAO,SAET,CACE/P,MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,UACP+P,MAAO,WAET,CACE/P,MAAO,UACP+P,MAAO,WAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,YAKdmG,UAAU,CACTlN,KAAM,YACN1J,KAAM,aACN6W,aAAc,OACdC,SAAU,CACR7D,QAAS,CACP,CACEvS,MAAO,OACP+P,MAAO,gBAET,CACE/P,MAAO,QACP+P,MAAO,SAET,CACE/P,MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,OACP+P,MAAO,YAKdmG,UAAU,CACTlN,KAAM,gBACN1J,KAAM,iBACN6W,aAAc,OACdC,SAAU,CACR7D,QAAS,CACP,CACEvS,MAAO,QACP+P,MAAO,UAET,CACE/P,MAAO,aACP+P,MAAO,eAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,YAKduG,iBAAiB,CAChBtN,KAAM,mBACN1J,KAAM,sCACN6W,cAAc","file":"module.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__0__;","module.exports = __WEBPACK_EXTERNAL_MODULE__1__;","module.exports = __WEBPACK_EXTERNAL_MODULE__2__;","module.exports = __WEBPACK_EXTERNAL_MODULE__3__;","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","export default function sum(values, valueof) {\n let sum = 0;\n if (valueof === undefined) {\n for (let value of values) {\n if (value = +value) {\n sum += value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if (value = +valueof(value, ++index, values)) {\n sum += value;\n }\n }\n }\n return sum;\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","import {min} from \"d3-array\";\n\nfunction targetDepth(d) {\n return d.target.depth;\n}\n\nexport function left(node) {\n return node.depth;\n}\n\nexport function right(node, n) {\n return n - 1 - node.height;\n}\n\nexport function justify(node, n) {\n return node.sourceLinks.length ? node.depth : n - 1;\n}\n\nexport function center(node) {\n return node.targetLinks.length ? node.depth\n : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1\n : 0;\n}\n","export default function constant(x) {\n return function() {\n return x;\n };\n}\n","import {max, min, sum} from \"d3-array\";\nimport {justify} from \"./align.js\";\nimport constant from \"./constant.js\";\n\nfunction ascendingSourceBreadth(a, b) {\n return ascendingBreadth(a.source, b.source) || a.index - b.index;\n}\n\nfunction ascendingTargetBreadth(a, b) {\n return ascendingBreadth(a.target, b.target) || a.index - b.index;\n}\n\nfunction ascendingBreadth(a, b) {\n return a.y0 - b.y0;\n}\n\nfunction value(d) {\n return d.value;\n}\n\nfunction defaultId(d) {\n return d.index;\n}\n\nfunction defaultNodes(graph) {\n return graph.nodes;\n}\n\nfunction defaultLinks(graph) {\n return graph.links;\n}\n\nfunction find(nodeById, id) {\n const node = nodeById.get(id);\n if (!node) throw new Error(\"missing: \" + id);\n return node;\n}\n\nfunction computeLinkBreadths({nodes}) {\n for (const node of nodes) {\n let y0 = node.y0;\n let y1 = y0;\n for (const link of node.sourceLinks) {\n link.y0 = y0 + link.width / 2;\n y0 += link.width;\n }\n for (const link of node.targetLinks) {\n link.y1 = y1 + link.width / 2;\n y1 += link.width;\n }\n }\n}\n\nexport default function Sankey() {\n let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent\n let dx = 24; // nodeWidth\n let dy = 8, py; // nodePadding\n let id = defaultId;\n let align = justify;\n let sort;\n let linkSort;\n let nodes = defaultNodes;\n let links = defaultLinks;\n let iterations = 6;\n\n function sankey() {\n const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)};\n computeNodeLinks(graph);\n computeNodeValues(graph);\n computeNodeDepths(graph);\n computeNodeHeights(graph);\n computeNodeBreadths(graph);\n computeLinkBreadths(graph);\n return graph;\n }\n\n sankey.update = function(graph) {\n computeLinkBreadths(graph);\n return graph;\n };\n\n sankey.nodeId = function(_) {\n return arguments.length ? (id = typeof _ === \"function\" ? _ : constant(_), sankey) : id;\n };\n\n sankey.nodeAlign = function(_) {\n return arguments.length ? (align = typeof _ === \"function\" ? _ : constant(_), sankey) : align;\n };\n\n sankey.nodeSort = function(_) {\n return arguments.length ? (sort = _, sankey) : sort;\n };\n\n sankey.nodeWidth = function(_) {\n return arguments.length ? (dx = +_, sankey) : dx;\n };\n\n sankey.nodePadding = function(_) {\n return arguments.length ? (dy = py = +_, sankey) : dy;\n };\n\n sankey.nodes = function(_) {\n return arguments.length ? (nodes = typeof _ === \"function\" ? _ : constant(_), sankey) : nodes;\n };\n\n sankey.links = function(_) {\n return arguments.length ? (links = typeof _ === \"function\" ? _ : constant(_), sankey) : links;\n };\n\n sankey.linkSort = function(_) {\n return arguments.length ? (linkSort = _, sankey) : linkSort;\n };\n\n sankey.size = function(_) {\n return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0];\n };\n\n sankey.extent = function(_) {\n return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]];\n };\n\n sankey.iterations = function(_) {\n return arguments.length ? (iterations = +_, sankey) : iterations;\n };\n\n function computeNodeLinks({nodes, links}) {\n for (const [i, node] of nodes.entries()) {\n node.index = i;\n node.sourceLinks = [];\n node.targetLinks = [];\n }\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d]));\n for (const [i, link] of links.entries()) {\n link.index = i;\n let {source, target} = link;\n if (typeof source !== \"object\") source = link.source = find(nodeById, source);\n if (typeof target !== \"object\") target = link.target = find(nodeById, target);\n source.sourceLinks.push(link);\n target.targetLinks.push(link);\n }\n if (linkSort != null) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(linkSort);\n targetLinks.sort(linkSort);\n }\n }\n }\n\n function computeNodeValues({nodes}) {\n for (const node of nodes) {\n node.value = node.fixedValue === undefined\n ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value))\n : node.fixedValue;\n }\n }\n\n function computeNodeDepths({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.depth = x;\n for (const {target} of node.sourceLinks) {\n next.add(target);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeHeights({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.height = x;\n for (const {source} of node.targetLinks) {\n next.add(source);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeLayers({nodes}) {\n const x = max(nodes, d => d.depth) + 1;\n const kx = (x1 - x0 - dx) / (x - 1);\n const columns = new Array(x);\n for (const node of nodes) {\n const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x))));\n node.layer = i;\n node.x0 = x0 + i * kx;\n node.x1 = node.x0 + dx;\n if (columns[i]) columns[i].push(node);\n else columns[i] = [node];\n }\n if (sort) for (const column of columns) {\n column.sort(sort);\n }\n return columns;\n }\n\n function initializeNodeBreadths(columns) {\n const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value));\n for (const nodes of columns) {\n let y = y0;\n for (const node of nodes) {\n node.y0 = y;\n node.y1 = y + node.value * ky;\n y = node.y1 + py;\n for (const link of node.sourceLinks) {\n link.width = link.value * ky;\n }\n }\n y = (y1 - y + py) / (nodes.length + 1);\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n node.y0 += y * (i + 1);\n node.y1 += y * (i + 1);\n }\n reorderLinks(nodes);\n }\n }\n\n function computeNodeBreadths(graph) {\n const columns = computeNodeLayers(graph);\n py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1));\n initializeNodeBreadths(columns);\n for (let i = 0; i < iterations; ++i) {\n const alpha = Math.pow(0.99, i);\n const beta = Math.max(1 - alpha, (i + 1) / iterations);\n relaxRightToLeft(columns, alpha, beta);\n relaxLeftToRight(columns, alpha, beta);\n }\n }\n\n // Reposition each node based on its incoming (target) links.\n function relaxLeftToRight(columns, alpha, beta) {\n for (let i = 1, n = columns.length; i < n; ++i) {\n const column = columns[i];\n for (const target of column) {\n let y = 0;\n let w = 0;\n for (const {source, value} of target.targetLinks) {\n let v = value * (target.layer - source.layer);\n y += targetTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - target.y0) * alpha;\n target.y0 += dy;\n target.y1 += dy;\n reorderNodeLinks(target);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n // Reposition each node based on its outgoing (source) links.\n function relaxRightToLeft(columns, alpha, beta) {\n for (let n = columns.length, i = n - 2; i >= 0; --i) {\n const column = columns[i];\n for (const source of column) {\n let y = 0;\n let w = 0;\n for (const {target, value} of source.sourceLinks) {\n let v = value * (target.layer - source.layer);\n y += sourceTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - source.y0) * alpha;\n source.y0 += dy;\n source.y1 += dy;\n reorderNodeLinks(source);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n function resolveCollisions(nodes, alpha) {\n const i = nodes.length >> 1;\n const subject = nodes[i];\n resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);\n resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);\n resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha);\n resolveCollisionsTopToBottom(nodes, y0, 0, alpha);\n }\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(nodes, y, i, alpha) {\n for (; i < nodes.length; ++i) {\n const node = nodes[i];\n const dy = (y - node.y0) * alpha;\n if (dy > 1e-6) node.y0 += dy, node.y1 += dy;\n y = node.y1 + py;\n }\n }\n\n // Push any overlapping nodes up.\n function resolveCollisionsBottomToTop(nodes, y, i, alpha) {\n for (; i >= 0; --i) {\n const node = nodes[i];\n const dy = (node.y1 - y) * alpha;\n if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy;\n y = node.y0 - py;\n }\n }\n\n function reorderNodeLinks({sourceLinks, targetLinks}) {\n if (linkSort === undefined) {\n for (const {source: {sourceLinks}} of targetLinks) {\n sourceLinks.sort(ascendingTargetBreadth);\n }\n for (const {target: {targetLinks}} of sourceLinks) {\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n function reorderLinks(nodes) {\n if (linkSort === undefined) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(ascendingTargetBreadth);\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n // Returns the target.y0 that would produce an ideal link from source to target.\n function targetTop(source, target) {\n let y = source.y0 - (source.sourceLinks.length - 1) * py / 2;\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y += width + py;\n }\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y -= width;\n }\n return y;\n }\n\n // Returns the source.y0 that would produce an ideal link from source to target.\n function sourceTop(source, target) {\n let y = target.y0 - (target.targetLinks.length - 1) * py / 2;\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y += width + py;\n }\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y -= width;\n }\n return y;\n }\n\n return sankey;\n}\n","var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n","export var slice = Array.prototype.slice;\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import {path} from \"d3-path\";\nimport {slice} from \"../array.js\";\nimport constant from \"../constant.js\";\nimport {x as pointX, y as pointY} from \"../point.js\";\nimport pointRadial from \"../pointRadial.js\";\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link(curve) {\n var source = linkSource,\n target = linkTarget,\n x = pointX,\n y = pointY,\n context = null;\n\n function link() {\n var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), link) : x;\n };\n\n link.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), link) : y;\n };\n\n link.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nexport function linkHorizontal() {\n return link(curveHorizontal);\n}\n\nexport function linkVertical() {\n return link(curveVertical);\n}\n\nexport function linkRadial() {\n var l = link(curveRadial);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n","import {linkHorizontal} from \"d3-shape\";\n\nfunction horizontalSource(d) {\n return [d.source.x1, d.y0];\n}\n\nfunction horizontalTarget(d) {\n return [d.target.x0, d.y1];\n}\n\nexport default function() {\n return linkHorizontal()\n .source(horizontalSource)\n .target(horizontalTarget);\n}\n","import * as d3 from 'd3';\nimport * as d3Sankey from 'd3-sankey';\n\nconst DISPLAY_VALUES = { total: 'total', percentage: 'percentage', both: 'both', none: 'none' };\nconst EDGE_COLORS = { none: 'none', path: 'path', input: 'input', output: 'output'};\n\nexport class Sankey {\n constructor(svg, container) {\n this._svg = svg;\n this._container = container || svg;\n this._gBound = null;\n\n this._data = null;\n this._nodes = null;\n this._links = null;\n\n this._width = 0;\n this._height = 0;\n this._boundedWidth = 0;\n this._boundedHeight = 0;\n\n this._marginTop = 20;\n this._marginRight = 20;\n this._marginBottom = 20;\n this._marginLeft = 20;\n\n this._background = 'rgba(0, 0, 0, 0)';\n this._edgeColor = 'path';\n this._colorScheme = 'Tableau10';\n this._colorScale = null;\n this._colorArray = '';\n\n this._sankeyAlignType = 'Justify';\n this._sankeyAlign = null;\n this._sankeyGenerator = null;\n this._sankeyNodeWith = 110;\n this._sankeyNodePadding = 20;\n\n this._svgNode = null;\n this._svgLink = null;\n\n this._displayValues = 'none';\n this._highlightOnHover = false;\n\n }\n \n _init() {\n this._setBoundDimensions();\n this._setColorScale();\n this._configureSankey();\n this._calculateSankey();\n }\n\n // ---------------------------- DIMENSIONS ----------------------------\n\n _setBoundDimensions() {\n this._boundedWidth = this._width - this._marginLeft - this._marginRight;\n this._boundedHeight = this._height - this._marginTop - this._marginBottom;\n }\n\n // ------------------------------ COLOR -------------------------------\n\n _setColorScale() {\n this._colorScale = d3.scaleOrdinal(d3[`scheme${this._colorScheme}`]);\n }\n\n _color(node) {\n return this._colorScale(node.name);\n }\n\n // ------------------------------ SANKEY -------------------------------\n\n _configureSankey() {\n this._sankeyAlign = d3Sankey[`sankey${this._sankeyAlignType}`];\n\n this._sankeyGenerator = d3Sankey\n .sankey()\n .nodeId(d => d.name)\n .nodeAlign(this._sankeyAlign)\n .nodeWidth(this._sankeyNodeWith)\n .nodePadding(this._sankeyNodePadding)\n .extent([\n [0, 0],\n [this._boundedWidth, this._boundedHeight],\n ]);\n }\n\n _calculateSankey() {\n const sankeyData = this._sankeyGenerator({\n nodes: this._data.nodes.map(d => Object.assign({}, d)),\n links: this._data.links.map(d => Object.assign({}, d))\n });\n\n this._nodes = sankeyData.nodes.filter(d => d.value !== 0);\n this._links = sankeyData.links.filter(d => d.value !== 0);\n }\n\n // ---------------------------- VALIDATIONS -----------------------------\n\n _validate() {\n return this._data &&\n this._data.nodes &&\n this._data.links &&\n this._data.nodes.length > 0 &&\n this._data.links.length > 0\n }\n\n // ------------------------------ HELPERS -------------------------------\n\n _setLinkGradient() {\n const gradient = this._svgLink\n .append('linearGradient')\n .attr('id', d => (d.uid = `link-${d.index}-${Math.random()}`))\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', d => d.source.x1)\n .attr('x2', d => d.target.x0);\n\n gradient\n .append('stop')\n .attr('offset', '0%')\n .attr('stop-color', d => this._color(d.source));\n\n gradient\n .append('stop')\n .attr('offset', '100%')\n .attr('stop-color', d => this._color(d.target));\n }\n\n _setLinkStroke(d) {\n switch (this._edgeColor) {\n case EDGE_COLORS.none:\n return '#aaa';\n case EDGE_COLORS.path:\n return `url(#${d.uid})`;\n case EDGE_COLORS.input:\n return this._color(d.source)\n case EDGE_COLORS.output:\n return this._color(d.target)\n default:\n return\n }\n }\n\n // NODE HOVER\n _showLinks(currentNode) {\n const linkedNodes = [];\n\n let traverse = [\n {\n linkType: 'sourceLinks',\n nodeType: 'target',\n },\n {\n linkType: 'targetLinks',\n nodeType: 'source',\n },\n ];\n\n traverse.forEach(step => {\n currentNode[step.linkType].forEach(l => {\n linkedNodes.push(l[step.nodeType]);\n });\n });\n\n // highlight linked nodes\n this._gBound\n .selectAll('.sankey-node')\n .style('opacity', node =>\n currentNode.name === node.name ||\n linkedNodes.find(linkedNode => linkedNode.name === node.name) ? \n '1' : '0.2'\n );\n\n // highlight links\n this._gBound\n .selectAll('.sankey-link')\n .style('opacity', link =>\n link && (\n link.source.name === currentNode.name || \n link.target.name === currentNode.name\n ) ? \n '1' : '0.2'\n );\n };\n\n _showAll() {\n this._gBound.selectAll('.sankey-node').style('opacity', '1');\n this._gBound.selectAll('.sankey-link').style('opacity', '1');\n };\n\n // NODE LABELING\n _formatValue(value) { return d3.format('.2~f')(value); }\n _formatPercent(percent) { return d3.format('.2~%')(percent); }\n _formatThousand(value) { return d3.format('.3~s')(value); }\n\n _labelNodeValue(currentNode) {\n const nodesAtDepth = this._nodes.filter(node => node.depth === currentNode.depth);\n const totalAtDepth = d3.sum(nodesAtDepth, node => node.value);\n const nodeValue = this._formatThousand(currentNode.value);\n const nodePercent = this._formatPercent(currentNode.value / totalAtDepth);\n\n let label = '';\n switch (this._displayValues) {\n case DISPLAY_VALUES.total:\n label = `${nodeValue}`;\n break;\n case DISPLAY_VALUES.percentage:\n label = `${nodePercent}`;\n break;\n case DISPLAY_VALUES.both:\n label = `${nodePercent} - ${nodeValue}`;\n break;\n default:\n break;\n }\n return label;\n };\n\n // ------------------------------ DRAWING -------------------------------\n\n _renderSVG() {\n // BACKGROUND\n this._container.style('background-color', this._background)\n\n // BOUNDS\n this._gBound = this._container.append('g')\n .attr('transform', `translate(${this._marginLeft}, ${this._marginTop})`);\n\n // NODES\n this._svgNode = this._gBound\n .append('g')\n .attr('stroke', '#000')\n .selectAll('.sankey-node')\n .data(this._nodes, node => node.name)\n .join('rect')\n .attr('class', 'sankey-node')\n .attr('id', d => d.name)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('height', d => d.y1 - d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('stroke', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .attr('fill', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .on('mouseover', d => this._highlightOnHover && this._showLinks(d))\n .on('mouseout', _ => this._highlightOnHover && this._showAll());\n\n // LINKS\n this._svgLink = this._gBound\n .append('g')\n .attr('fill', 'none')\n .attr('stroke-opacity', 0.3)\n .selectAll('g')\n .data(this._links, link => `${link.source.name}-${link.target.name}`)\n .join('g')\n .style('mix-blend-mode', 'multiply');\n\n if (this._edgeColor === 'path') this._setLinkGradient()\n\n this._svgLink\n .append('path')\n .attr('class', 'sankey-link')\n .attr('d', d3Sankey.sankeyLinkHorizontal())\n .attr('stroke', \"rgba(182, 185, 196, 1)\")\n .attr('stroke-width', d => Math.max(1, d.width)); \n\n // LABELS\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('y', d => (d.y1 + d.y0) / 2)\n .attr('dy', '0.35em')\n .text(d => d.name);\n\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('font-size', 14)\n .attr('font-weight', '700')\n .attr('y', d => ((d.y1 + d.y0) / 2) + 16)\n .attr('dy', '0.35em')\n .text(d => this._labelNodeValue(d));\n\n this._svgNode\n .append('title')\n .text(d => `${d.name}\\n${this._formatValue(d.value)}`);\n\n this._svgLink\n .append('title')\n .text(d => `${d.source.name} → ${d.target.name}\\n${this._formatValue(d.value)}`);\n }\n\n\n // ----------------------------------------------------------------------- \n // ------------------------------ API ------------------------------\n // ----------------------------------------------------------------------- \n\n data(_) {\n return arguments.length ? (this._data = _, this) : this._data;\n };\n\n width(_) {\n return arguments.length ? (this._width = +_, this) : this._width;\n };\n\n height(_) {\n return arguments.length ? (this._height = +_, this) : this._height;\n };\n\n align(_) {\n return arguments.length ? (this._sankeyAlignType = _, this) : this._sankeyAlignType;\n }\n\n colorScheme(_) {\n return arguments.length ? (this._colorScheme = _, this) : this._colorScheme;\n }\n\n colorArray(_) {\n return arguments.length ? (this._colorArray = _, this) : this._colorArray;\n }\n\n edgeColor(_) {\n return arguments.length ? (this._edgeColor = _, this) : this._edgeColor;\n }\n\n displayValues(_) {\n return arguments.length ? (this._displayValues = _, this) : this._displayValues;\n }\n\n highlightOnHover(_) {\n return arguments.length ? (this._highlightOnHover = _, this) : this._highlightOnHover;\n }\n\n render() {\n if (!this._validate()) {\n // no graph data\n }\n else {\n this._init();\n this._renderSVG()\n }\n return this;\n }\n}\n","// @ts-nocheck\nimport React from 'react';\nimport { Icon } from '@grafana/ui';\n\nexport const ErrorMessage = ({ message }) => ( \n

\n

\n \n
{message}
\n
\n

\n)\n\nconst panelStyles = {\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n}\n\nconst containerStyles = {\n padding: '15px 20px',\n marginBottom: '4px',\n position: 'relative',\n color: 'rgb(255, 255, 255)',\n textShadow: 'rgb(0 0 0 / 20%) 0px 1px 0px',\n borderRadius: '3px',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n background: 'linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))'\n}\n\nconst messageStyles = {\n marginLeft: 10\n}\n","const SHOULD_LOG = true;\n\nexport const logger = fnLogger();\n\nfunction fnLogger(shouldLog = SHOULD_LOG) {\n if (!shouldLog) {\n return {\n warn: (..._: any[]) => undefined,\n error: (..._: any[]) => undefined,\n log: (..._: any[]) => undefined,\n };\n }\n\n return {\n warn: console.warn,\n error: console.error,\n log: console.log,\n };\n}\n","// @ts-nocheck\nimport React, { useState, useEffect } from 'react';\nimport * as d3 from 'd3';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyOptions } from 'types';\nimport { Sankey } from 'Sankey'\nimport { ErrorMessage } from 'Error'\nimport { logger } from 'fn-logger';\n\ninterface Props extends PanelProps {}\n\nexport const SankeyPanel: React.FC = ({ options, data, width, height }) => {\n // ------------------------ CHART CONSTANTS -----------------------\n const CHART_REQUIRED_FIELDS = { source: 'source', target: 'target', value: 'value' };\n\n // ------------------------ ERROR MESSAGES ------------------------\n const requiredFieldsMsg = `Required fields not present: ${Object.keys(CHART_REQUIRED_FIELDS).join(', ')}`;\n const fieldTypeMsg = `Fields should have the following types: source (string), target (string), value (numeric)`;\n\n // ------------------------- REACT HOOKS --------------------------\n const [ error, setError ] = useState({ isError: false, message: '' })\n const [ graph, setGraph ] = useState({ nodes: [], links: [] })\n\n useEffect(() => {\n if (data.error) {\n logger.warn('[FN] Sankey data error.',{data, error: data.error})\n }\n\n data.error\n ?\n setError({isError: true, message: data.error.message})\n :\n setGraph(buildGraph())\n }, [data])\n\n // ------------------------- DATA ACQUISITION -------------------------\n const validate = (sources, targets, values) => {\n let isValid = true;\n\n // REQUIRED FIELDS\n if (!(sources && targets && values)) {\n setError({ isError: true, message: requiredFieldsMsg })\n return isValid = false;\n }\n\n // FIELD TYPES\n const sourcesString = sources.every(d => typeof d === 'string')\n const targetsString = targets.every(d => typeof d === 'string')\n const valuesNumeric = values.every(d => typeof d === 'number')\n\n if (!(sourcesString && targetsString && valuesNumeric)) {\n setError({ isError: true, message: fieldTypeMsg })\n return isValid = false;\n }\n\n setError({});\n\n return isValid;\n }\n\n const buildGraph = () => {\n const frame = data.series[0];\n\n const sourceAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.source);\n const targetAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.target);\n const valueAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.value);\n\n const sources = sourceAccesor?.values.toArray();\n const targets = targetAccesor?.values.toArray();\n const values = valueAccesor?.values.toArray();\n\n const isValid = validate(sources, targets, values);\n if (!isValid) {return}\n\n const zip = d3.zip(sources, targets, values);\n\n const nodes = Array.from(new Set(sources.concat(targets))).map(node => ({ name: node }));\n const links = zip.map(d => ({ source: d[0], target: d[1], value: +d[2].toFixed(2) }));\n const graph = { nodes, links };\n\n return graph\n }\n\n // ------------------------------- CHART ------------------------------\n const chart = svg => {\n const sankey = new Sankey(svg)\n .width(width)\n .height(height)\n .align(options.align)\n .edgeColor(options.edgeColor)\n .colorScheme(options.colorScheme)\n .displayValues(options.displayValues)\n .highlightOnHover(options.highlightOnHover)\n .colorArray(options.colorArray)\n .data(graph)\n\n try {\n sankey.render();\n } catch (renderError) {\n logger.warn('[FN] Sankey render error.',{renderError, graph})\n\n setError({isError: true, message: renderError.message})\n }\n };\n\n return (error.isError ?\n \n :\n {\n d3.select(node)\n .selectAll('*')\n .remove();\n d3.select(node).call(chart);\n }}\n />\n );\n};\n","// NOTE: implementation of toDataFrame: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/dataframe/processDataFrame.ts\nimport { toDataFrame, FieldType, ArrayVector, Field } from '@grafana/data';\nimport { logger } from 'fn-logger';\n\nimport { SankeyOptionsFn } from 'types-fn';\n\nexport function transformFnData(): Required['transformFn'] {\n return ({ series, ...other }) => {\n const transformedSeries = series.map((data) => {\n return toDataFrame({ ...data, fields: data.fields.map(mapField()) });\n });\n\n return {\n series: transformedSeries,\n ...other,\n };\n };\n}\n\nconst SANKEY_FIELD_NAMES = ['source', 'target', 'value'];\n\n// @ts-ignore\nfunction mapField

() {\n return (field: Field

, _: number, __: Array>) => {\n const isSankeyField = SANKEY_FIELD_NAMES.includes(field.name);\n\n const isArrayVector = field.values instanceof ArrayVector || typeof field.values?.toArray === 'function';\n const isArray = Array.isArray(field.values);\n\n if (!isSankeyField || !field.values || (!isArray && !isArrayVector)) {\n return field;\n }\n\n const values = isArrayVector ? field.values.toArray() : isArray ? field.values : null;\n\n if (values === null) {\n logger.warn('[FN] Failed to transform sankey data.', 'Values are not an array.');\n\n return {\n ...field,\n values: new ArrayVector([]),\n };\n }\n\n const parsedValues = isSankeyField ? ((values as P[]).map(splitValue())[0] as unknown[]).map(mapToNumber()) : null;\n\n try {\n return {\n ...field,\n type: parsedValues?.every(isNumber()) ? FieldType.number : field.type,\n values: parsedValues ? new ArrayVector(JSON.parse(JSON.stringify(parsedValues))) : values,\n };\n } catch (err) {\n logger.warn('[FN] Failed to transform sankey data.', err instanceof Error ? err.message : String(err));\n\n return {\n ...field,\n type: field.type,\n values: new ArrayVector([]),\n };\n }\n };\n}\n\n// @ts-ignore\nfunction mapToNumber() {\n return (value: V, _: number, __: V[]) => (Number.isNaN(Number(value)) ? value : Number(value));\n}\n\n// @ts-ignore\nfunction splitValue() {\n return (value: V) => (typeof value === 'string' ? value.split('|') : value);\n}\n\n// @ts-ignore\nfunction isNumber() {\n return (value: V) => typeof value === 'number';\n}\n","import { PanelPlugin } from '@grafana/data';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { SankeyPanelFn as SankeyPanel } from './SankeyPanelFn';\n\nexport const plugin = new PanelPlugin(SankeyPanel).setPanelOptions((builder) => {\n return builder\n .addSelect({\n path: 'align',\n name: 'Align',\n defaultValue: 'Justify',\n settings: {\n options: [\n {\n value: 'Justify',\n label: 'Justify',\n },\n {\n value: 'Left',\n label: 'Left',\n },\n {\n value: 'Right',\n label: 'Right',\n },\n {\n value: 'Center',\n label: 'Center',\n },\n ],\n },\n })\n .addTextInput({\n path: 'colorArray',\n name: 'Color Object',\n defaultValue: '',\n })\n .addSelect({\n path: 'colorScheme',\n name: 'Color',\n defaultValue: 'Tableau10',\n settings: {\n options: [\n {\n value: 'Tableau10',\n label: 'Tableau10',\n },\n {\n value: 'Category10',\n label: 'Category10',\n },\n {\n value: 'Accent',\n label: 'Accent',\n },\n {\n value: 'Dark2',\n label: 'Dark2',\n },\n {\n value: 'Paired',\n label: 'Paired',\n },\n {\n value: 'Pastel1',\n label: 'Pastel1',\n },\n {\n value: 'Pastel2',\n label: 'Pastel2',\n },\n {\n value: 'Set1',\n label: 'Set1',\n },\n {\n value: 'Set2',\n label: 'Set2',\n },\n {\n value: 'Set3',\n label: 'Set3',\n },\n ],\n },\n })\n .addSelect({\n path: 'edgeColor',\n name: 'Edge Color',\n defaultValue: 'path',\n settings: {\n options: [\n {\n value: 'path',\n label: 'input-output',\n },\n {\n value: 'input',\n label: 'input',\n },\n {\n value: 'output',\n label: 'output',\n },\n {\n value: 'none',\n label: 'none',\n },\n ],\n },\n })\n .addSelect({\n path: 'displayValues',\n name: 'Display Values',\n defaultValue: 'none',\n settings: {\n options: [\n {\n value: 'total',\n label: 'Totals',\n },\n {\n value: 'percentage',\n label: 'Percentages',\n },\n {\n value: 'both',\n label: 'Both',\n },\n {\n value: 'none',\n label: 'None',\n },\n ],\n },\n })\n .addBooleanSwitch({\n path: 'highlightOnHover',\n name: 'Highlight connections on node hover',\n defaultValue: false,\n });\n});\n","import React, { useMemo, FC } from 'react';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyPanel } from 'SankeyPanel';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { transformFnData } from 'transform-fn-data';\n\nexport interface SankeyPanelFnProps extends PanelProps {}\n\nexport const SankeyPanelFn: FC = ({ data, ...props }) => {\n const transformFn = useMemo(transformFnData, []);\n\n const transformedData = useMemo(() => transformFn(data), [transformFn, data]);\n\n return ;\n};\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///external \"react\"","webpack:///external \"d3\"","webpack:///external \"@grafana/data\"","webpack:///external \"@grafana/ui\"","webpack:///../node_modules/tslib/tslib.es6.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/sum.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/max.js","webpack:///../node_modules/d3-sankey/node_modules/d3-array/src/min.js","webpack:///../node_modules/d3-sankey/src/align.js","webpack:///../node_modules/d3-sankey/src/constant.js","webpack:///../node_modules/d3-sankey/src/sankey.js","webpack:///../node_modules/d3-path/src/path.js","webpack:///../node_modules/d3-shape/src/array.js","webpack:///../node_modules/d3-shape/src/constant.js","webpack:///../node_modules/d3-shape/src/point.js","webpack:///../node_modules/d3-shape/src/link/index.js","webpack:///../node_modules/d3-sankey/src/sankeyLinkHorizontal.js","webpack:///./Sankey.js","webpack:///./Error.tsx","webpack:///./fn-logger.ts","webpack:///./SankeyPanel.tsx","webpack:///./transform-fn-data.ts","webpack:///./module.ts","webpack:///./SankeyPanelFn.tsx"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","__WEBPACK_EXTERNAL_MODULE__0__","__WEBPACK_EXTERNAL_MODULE__1__","__WEBPACK_EXTERNAL_MODULE__2__","__WEBPACK_EXTERNAL_MODULE__3__","__assign","assign","arguments","length","apply","this","__rest","e","indexOf","getOwnPropertySymbols","propertyIsEnumerable","__read","iterator","ar","next","done","push","error","sum","values","valueof","undefined","index","max","min","targetDepth","target","depth","left","node","right","height","justify","sourceLinks","center","targetLinks","constant","x","ascendingSourceBreadth","a","b","ascendingBreadth","source","ascendingTargetBreadth","y0","defaultId","defaultNodes","graph","nodes","defaultLinks","links","find","nodeById","id","Error","computeLinkBreadths","y1","link","width","py","sort","linkSort","x0","x1","dx","dy","align","iterations","sankey","computeNodeLinks","computeNodeValues","computeNodeDepths","computeNodeHeights","computeNodeBreadths","entries","Map","map","fixedValue","Math","current","Set","size","add","columns","kx","Array","floor","layer","column","computeNodeLayers","ky","y","reorderLinks","initializeNodeBreadths","alpha","pow","beta","relaxRightToLeft","relaxLeftToRight","w","v","targetTop","reorderNodeLinks","resolveCollisions","sourceTop","subject","resolveCollisionsBottomToTop","resolveCollisionsTopToBottom","update","nodeId","_","nodeAlign","nodeSort","nodeWidth","nodePadding","extent","pi","PI","tau","tauEpsilon","Path","_x0","_y0","_x1","_y1","path","constructor","moveTo","closePath","lineTo","quadraticCurveTo","bezierCurveTo","x2","y2","arcTo","x21","y21","x01","y01","l01_2","abs","x20","y20","l21_2","l20_2","l21","sqrt","l01","tan","acos","t01","t21","arc","a0","a1","ccw","cos","sin","cw","da","rect","h","toString","slice","linkSource","linkTarget","curve","context","buffer","argv","curveHorizontal","horizontalSource","horizontalTarget","DISPLAY_VALUES","EDGE_COLORS","Sankey","svg","container","_svg","_container","_gBound","_data","_nodes","_links","_width","_height","_boundedWidth","_boundedHeight","_marginTop","_marginRight","_marginBottom","_marginLeft","_background","_edgeColor","_colorScheme","_colorScale","_colorArray","_sankeyAlignType","_sankeyAlign","_sankeyGenerator","_sankeyNodeWith","_sankeyNodePadding","_svgNode","_svgLink","_displayValues","_highlightOnHover","_setBoundDimensions","_setColorScale","_configureSankey","_calculateSankey","d3","d3Sankey","sankeyData","filter","gradient","append","attr","uid","random","_color","currentNode","linkedNodes","linkType","nodeType","forEach","step","selectAll","style","linkedNode","percent","nodesAtDepth","totalAtDepth","nodeValue","_formatThousand","nodePercent","_formatPercent","label","data","join","colorArray","JSON","parse","keys","includes","on","_showLinks","__data__","_showAll","_setLinkGradient","text","_labelNodeValue","_formatValue","_validate","_init","_renderSVG","message","panelStyles","containerStyles","messageStyles","display","justifyContent","alignItems","padding","marginBottom","position","color","textShadow","borderRadius","flexDirection","background","marginLeft","logger","shouldLog","warn","log","console","fnLogger","options","CHART_REQUIRED_FIELDS","requiredFieldsMsg","isError","setError","setGraph","buildGraph","frame","series","sourceAccesor","fields","field","targetAccesor","valueAccesor","sources","toArray","targets","isValid","sourcesString","every","targetsString","valuesNumeric","validate","zip","from","concat","toFixed","chart","edgeColor","colorScheme","displayValues","highlightOnHover","render","renderError","viewBox","ref","remove","transformFnData","other","transformedSeries","__","isSankeyField","SANKEY_FIELD_NAMES","isArrayVector","isArray","parsedValues","split","Number","isNaN","type","number","stringify","err","String","props","transformFn","transformedData","setPanelOptions","builder","addSelect","defaultValue","settings","addTextInput","addBooleanSwitch"],"mappings":"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P,MAAO,aACP+P,MAAO,cAET,CACE/P,MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,QACP+P,MAAO,SAET,CACE/P,MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,UACP+P,MAAO,WAET,CACE/P,MAAO,UACP+P,MAAO,WAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,YAKdoG,UAAU,CACTnN,KAAM,YACN1J,KAAM,aACN8W,aAAc,OACdC,SAAU,CACR7D,QAAS,CACP,CACExS,MAAO,OACP+P,MAAO,gBAET,CACE/P,MAAO,QACP+P,MAAO,SAET,CACE/P,MAAO,SACP+P,MAAO,UAET,CACE/P,MAAO,OACP+P,MAAO,YAKdoG,UAAU,CACTnN,KAAM,gBACN1J,KAAM,iBACN8W,aAAc,OACdC,SAAU,CACR7D,QAAS,CACP,CACExS,MAAO,QACP+P,MAAO,UAET,CACE/P,MAAO,aACP+P,MAAO,eAET,CACE/P,MAAO,OACP+P,MAAO,QAET,CACE/P,MAAO,OACP+P,MAAO,YAKdwG,iBAAiB,CAChBvN,KAAM,mBACN1J,KAAM,sCACN8W,cAAc","file":"module.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__0__;","module.exports = __WEBPACK_EXTERNAL_MODULE__1__;","module.exports = __WEBPACK_EXTERNAL_MODULE__2__;","module.exports = __WEBPACK_EXTERNAL_MODULE__3__;","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","export default function sum(values, valueof) {\n let sum = 0;\n if (valueof === undefined) {\n for (let value of values) {\n if (value = +value) {\n sum += value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if (value = +valueof(value, ++index, values)) {\n sum += value;\n }\n }\n }\n return sum;\n}\n","export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n","export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n","import {min} from \"d3-array\";\n\nfunction targetDepth(d) {\n return d.target.depth;\n}\n\nexport function left(node) {\n return node.depth;\n}\n\nexport function right(node, n) {\n return n - 1 - node.height;\n}\n\nexport function justify(node, n) {\n return node.sourceLinks.length ? node.depth : n - 1;\n}\n\nexport function center(node) {\n return node.targetLinks.length ? node.depth\n : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1\n : 0;\n}\n","export default function constant(x) {\n return function() {\n return x;\n };\n}\n","import {max, min, sum} from \"d3-array\";\nimport {justify} from \"./align.js\";\nimport constant from \"./constant.js\";\n\nfunction ascendingSourceBreadth(a, b) {\n return ascendingBreadth(a.source, b.source) || a.index - b.index;\n}\n\nfunction ascendingTargetBreadth(a, b) {\n return ascendingBreadth(a.target, b.target) || a.index - b.index;\n}\n\nfunction ascendingBreadth(a, b) {\n return a.y0 - b.y0;\n}\n\nfunction value(d) {\n return d.value;\n}\n\nfunction defaultId(d) {\n return d.index;\n}\n\nfunction defaultNodes(graph) {\n return graph.nodes;\n}\n\nfunction defaultLinks(graph) {\n return graph.links;\n}\n\nfunction find(nodeById, id) {\n const node = nodeById.get(id);\n if (!node) throw new Error(\"missing: \" + id);\n return node;\n}\n\nfunction computeLinkBreadths({nodes}) {\n for (const node of nodes) {\n let y0 = node.y0;\n let y1 = y0;\n for (const link of node.sourceLinks) {\n link.y0 = y0 + link.width / 2;\n y0 += link.width;\n }\n for (const link of node.targetLinks) {\n link.y1 = y1 + link.width / 2;\n y1 += link.width;\n }\n }\n}\n\nexport default function Sankey() {\n let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent\n let dx = 24; // nodeWidth\n let dy = 8, py; // nodePadding\n let id = defaultId;\n let align = justify;\n let sort;\n let linkSort;\n let nodes = defaultNodes;\n let links = defaultLinks;\n let iterations = 6;\n\n function sankey() {\n const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)};\n computeNodeLinks(graph);\n computeNodeValues(graph);\n computeNodeDepths(graph);\n computeNodeHeights(graph);\n computeNodeBreadths(graph);\n computeLinkBreadths(graph);\n return graph;\n }\n\n sankey.update = function(graph) {\n computeLinkBreadths(graph);\n return graph;\n };\n\n sankey.nodeId = function(_) {\n return arguments.length ? (id = typeof _ === \"function\" ? _ : constant(_), sankey) : id;\n };\n\n sankey.nodeAlign = function(_) {\n return arguments.length ? (align = typeof _ === \"function\" ? _ : constant(_), sankey) : align;\n };\n\n sankey.nodeSort = function(_) {\n return arguments.length ? (sort = _, sankey) : sort;\n };\n\n sankey.nodeWidth = function(_) {\n return arguments.length ? (dx = +_, sankey) : dx;\n };\n\n sankey.nodePadding = function(_) {\n return arguments.length ? (dy = py = +_, sankey) : dy;\n };\n\n sankey.nodes = function(_) {\n return arguments.length ? (nodes = typeof _ === \"function\" ? _ : constant(_), sankey) : nodes;\n };\n\n sankey.links = function(_) {\n return arguments.length ? (links = typeof _ === \"function\" ? _ : constant(_), sankey) : links;\n };\n\n sankey.linkSort = function(_) {\n return arguments.length ? (linkSort = _, sankey) : linkSort;\n };\n\n sankey.size = function(_) {\n return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0];\n };\n\n sankey.extent = function(_) {\n return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]];\n };\n\n sankey.iterations = function(_) {\n return arguments.length ? (iterations = +_, sankey) : iterations;\n };\n\n function computeNodeLinks({nodes, links}) {\n for (const [i, node] of nodes.entries()) {\n node.index = i;\n node.sourceLinks = [];\n node.targetLinks = [];\n }\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d]));\n for (const [i, link] of links.entries()) {\n link.index = i;\n let {source, target} = link;\n if (typeof source !== \"object\") source = link.source = find(nodeById, source);\n if (typeof target !== \"object\") target = link.target = find(nodeById, target);\n source.sourceLinks.push(link);\n target.targetLinks.push(link);\n }\n if (linkSort != null) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(linkSort);\n targetLinks.sort(linkSort);\n }\n }\n }\n\n function computeNodeValues({nodes}) {\n for (const node of nodes) {\n node.value = node.fixedValue === undefined\n ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value))\n : node.fixedValue;\n }\n }\n\n function computeNodeDepths({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.depth = x;\n for (const {target} of node.sourceLinks) {\n next.add(target);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeHeights({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.height = x;\n for (const {source} of node.targetLinks) {\n next.add(source);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeLayers({nodes}) {\n const x = max(nodes, d => d.depth) + 1;\n const kx = (x1 - x0 - dx) / (x - 1);\n const columns = new Array(x);\n for (const node of nodes) {\n const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x))));\n node.layer = i;\n node.x0 = x0 + i * kx;\n node.x1 = node.x0 + dx;\n if (columns[i]) columns[i].push(node);\n else columns[i] = [node];\n }\n if (sort) for (const column of columns) {\n column.sort(sort);\n }\n return columns;\n }\n\n function initializeNodeBreadths(columns) {\n const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value));\n for (const nodes of columns) {\n let y = y0;\n for (const node of nodes) {\n node.y0 = y;\n node.y1 = y + node.value * ky;\n y = node.y1 + py;\n for (const link of node.sourceLinks) {\n link.width = link.value * ky;\n }\n }\n y = (y1 - y + py) / (nodes.length + 1);\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n node.y0 += y * (i + 1);\n node.y1 += y * (i + 1);\n }\n reorderLinks(nodes);\n }\n }\n\n function computeNodeBreadths(graph) {\n const columns = computeNodeLayers(graph);\n py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1));\n initializeNodeBreadths(columns);\n for (let i = 0; i < iterations; ++i) {\n const alpha = Math.pow(0.99, i);\n const beta = Math.max(1 - alpha, (i + 1) / iterations);\n relaxRightToLeft(columns, alpha, beta);\n relaxLeftToRight(columns, alpha, beta);\n }\n }\n\n // Reposition each node based on its incoming (target) links.\n function relaxLeftToRight(columns, alpha, beta) {\n for (let i = 1, n = columns.length; i < n; ++i) {\n const column = columns[i];\n for (const target of column) {\n let y = 0;\n let w = 0;\n for (const {source, value} of target.targetLinks) {\n let v = value * (target.layer - source.layer);\n y += targetTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - target.y0) * alpha;\n target.y0 += dy;\n target.y1 += dy;\n reorderNodeLinks(target);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n // Reposition each node based on its outgoing (source) links.\n function relaxRightToLeft(columns, alpha, beta) {\n for (let n = columns.length, i = n - 2; i >= 0; --i) {\n const column = columns[i];\n for (const source of column) {\n let y = 0;\n let w = 0;\n for (const {target, value} of source.sourceLinks) {\n let v = value * (target.layer - source.layer);\n y += sourceTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - source.y0) * alpha;\n source.y0 += dy;\n source.y1 += dy;\n reorderNodeLinks(source);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n function resolveCollisions(nodes, alpha) {\n const i = nodes.length >> 1;\n const subject = nodes[i];\n resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);\n resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);\n resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha);\n resolveCollisionsTopToBottom(nodes, y0, 0, alpha);\n }\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(nodes, y, i, alpha) {\n for (; i < nodes.length; ++i) {\n const node = nodes[i];\n const dy = (y - node.y0) * alpha;\n if (dy > 1e-6) node.y0 += dy, node.y1 += dy;\n y = node.y1 + py;\n }\n }\n\n // Push any overlapping nodes up.\n function resolveCollisionsBottomToTop(nodes, y, i, alpha) {\n for (; i >= 0; --i) {\n const node = nodes[i];\n const dy = (node.y1 - y) * alpha;\n if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy;\n y = node.y0 - py;\n }\n }\n\n function reorderNodeLinks({sourceLinks, targetLinks}) {\n if (linkSort === undefined) {\n for (const {source: {sourceLinks}} of targetLinks) {\n sourceLinks.sort(ascendingTargetBreadth);\n }\n for (const {target: {targetLinks}} of sourceLinks) {\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n function reorderLinks(nodes) {\n if (linkSort === undefined) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(ascendingTargetBreadth);\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n // Returns the target.y0 that would produce an ideal link from source to target.\n function targetTop(source, target) {\n let y = source.y0 - (source.sourceLinks.length - 1) * py / 2;\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y += width + py;\n }\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y -= width;\n }\n return y;\n }\n\n // Returns the source.y0 that would produce an ideal link from source to target.\n function sourceTop(source, target) {\n let y = target.y0 - (target.targetLinks.length - 1) * py / 2;\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y += width + py;\n }\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y -= width;\n }\n return y;\n }\n\n return sankey;\n}\n","var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n","export var slice = Array.prototype.slice;\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import {path} from \"d3-path\";\nimport {slice} from \"../array.js\";\nimport constant from \"../constant.js\";\nimport {x as pointX, y as pointY} from \"../point.js\";\nimport pointRadial from \"../pointRadial.js\";\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link(curve) {\n var source = linkSource,\n target = linkTarget,\n x = pointX,\n y = pointY,\n context = null;\n\n function link() {\n var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), link) : x;\n };\n\n link.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), link) : y;\n };\n\n link.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nexport function linkHorizontal() {\n return link(curveHorizontal);\n}\n\nexport function linkVertical() {\n return link(curveVertical);\n}\n\nexport function linkRadial() {\n var l = link(curveRadial);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n","import {linkHorizontal} from \"d3-shape\";\n\nfunction horizontalSource(d) {\n return [d.source.x1, d.y0];\n}\n\nfunction horizontalTarget(d) {\n return [d.target.x0, d.y1];\n}\n\nexport default function() {\n return linkHorizontal()\n .source(horizontalSource)\n .target(horizontalTarget);\n}\n","import * as d3 from 'd3';\nimport * as d3Sankey from 'd3-sankey';\n\nconst DISPLAY_VALUES = { total: 'total', percentage: 'percentage', both: 'both', none: 'none' };\nconst EDGE_COLORS = { none: 'none', path: 'path', input: 'input', output: 'output'};\n\nexport class Sankey {\n constructor(svg, container) {\n this._svg = svg;\n this._container = container || svg;\n this._gBound = null;\n\n this._data = null;\n this._nodes = null;\n this._links = null;\n\n this._width = 0;\n this._height = 0;\n this._boundedWidth = 0;\n this._boundedHeight = 0;\n\n this._marginTop = 20;\n this._marginRight = 20;\n this._marginBottom = 20;\n this._marginLeft = 20;\n\n this._background = 'rgba(0, 0, 0, 0)';\n this._edgeColor = 'path';\n this._colorScheme = 'Tableau10';\n this._colorScale = null;\n this._colorArray = '';\n\n this._sankeyAlignType = 'Justify';\n this._sankeyAlign = null;\n this._sankeyGenerator = null;\n this._sankeyNodeWith = 110;\n this._sankeyNodePadding = 20;\n\n this._svgNode = null;\n this._svgLink = null;\n\n this._displayValues = 'none';\n this._highlightOnHover = false;\n\n }\n \n _init() {\n this._setBoundDimensions();\n this._setColorScale();\n this._configureSankey();\n this._calculateSankey();\n }\n\n // ---------------------------- DIMENSIONS ----------------------------\n\n _setBoundDimensions() {\n this._boundedWidth = this._width - this._marginLeft - this._marginRight;\n this._boundedHeight = this._height - this._marginTop - this._marginBottom;\n }\n\n // ------------------------------ COLOR -------------------------------\n\n _setColorScale() {\n this._colorScale = d3.scaleOrdinal(d3[`scheme${this._colorScheme}`]);\n }\n\n _color(node) {\n return this._colorScale(node.name);\n }\n\n // ------------------------------ SANKEY -------------------------------\n\n _configureSankey() {\n this._sankeyAlign = d3Sankey[`sankey${this._sankeyAlignType}`];\n\n this._sankeyGenerator = d3Sankey\n .sankey()\n .nodeId(d => d.name)\n .nodeAlign(this._sankeyAlign)\n .nodeWidth(this._sankeyNodeWith)\n .nodePadding(this._sankeyNodePadding)\n .extent([\n [0, 0],\n [this._boundedWidth, this._boundedHeight],\n ]);\n }\n\n _calculateSankey() {\n const sankeyData = this._sankeyGenerator({\n nodes: this._data.nodes.map(d => Object.assign({}, d)),\n links: this._data.links.map(d => Object.assign({}, d))\n });\n\n this._nodes = sankeyData.nodes.filter(d => d.value !== 0);\n this._links = sankeyData.links.filter(d => d.value !== 0);\n }\n\n // ---------------------------- VALIDATIONS -----------------------------\n\n _validate() {\n return this._data &&\n this._data.nodes &&\n this._data.links &&\n this._data.nodes.length > 0 &&\n this._data.links.length > 0\n }\n\n // ------------------------------ HELPERS -------------------------------\n\n _setLinkGradient() {\n const gradient = this._svgLink\n .append('linearGradient')\n .attr('id', d => (d.uid = `link-${d.index}-${Math.random()}`))\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', d => d.source.x1)\n .attr('x2', d => d.target.x0);\n\n gradient\n .append('stop')\n .attr('offset', '0%')\n .attr('stop-color', d => this._color(d.source));\n\n gradient\n .append('stop')\n .attr('offset', '100%')\n .attr('stop-color', d => this._color(d.target));\n }\n\n _setLinkStroke(d) {\n switch (this._edgeColor) {\n case EDGE_COLORS.none:\n return '#aaa';\n case EDGE_COLORS.path:\n return `url(#${d.uid})`;\n case EDGE_COLORS.input:\n return this._color(d.source)\n case EDGE_COLORS.output:\n return this._color(d.target)\n default:\n return\n }\n }\n\n // NODE HOVER\n _showLinks(currentNode) {\n const linkedNodes = [];\n\n let traverse = [\n {\n linkType: 'sourceLinks',\n nodeType: 'target',\n },\n {\n linkType: 'targetLinks',\n nodeType: 'source',\n },\n ];\n\n traverse.forEach(step => {\n currentNode[step.linkType].forEach(l => {\n linkedNodes.push(l[step.nodeType]);\n });\n });\n\n // highlight linked nodes\n this._gBound\n .selectAll('.sankey-node')\n .style('opacity', node =>\n currentNode.name === node.name ||\n linkedNodes.find(linkedNode => linkedNode.name === node.name) ? \n '1' : '0.2'\n );\n\n // highlight links\n this._gBound\n .selectAll('.sankey-link')\n .style('opacity', link =>\n link && (\n link.source.name === currentNode.name || \n link.target.name === currentNode.name\n ) ? \n '1' : '0.2'\n );\n };\n\n _showAll() {\n this._gBound.selectAll('.sankey-node').style('opacity', '1');\n this._gBound.selectAll('.sankey-link').style('opacity', '1');\n };\n\n // NODE LABELING\n _formatValue(value) { return d3.format('.2~f')(value); }\n _formatPercent(percent) { return d3.format('.2~%')(percent); }\n _formatThousand(value) { return d3.format('.3~s')(value); }\n\n _labelNodeValue(currentNode) {\n const nodesAtDepth = this._nodes.filter(node => node.depth === currentNode.depth);\n const totalAtDepth = d3.sum(nodesAtDepth, node => node.value);\n const nodeValue = this._formatThousand(currentNode.value);\n const nodePercent = this._formatPercent(currentNode.value / totalAtDepth);\n\n let label = '';\n switch (this._displayValues) {\n case DISPLAY_VALUES.total:\n label = `${nodeValue}`;\n break;\n case DISPLAY_VALUES.percentage:\n label = `${nodePercent}`;\n break;\n case DISPLAY_VALUES.both:\n label = `${nodePercent} - ${nodeValue}`;\n break;\n default:\n break;\n }\n return label;\n };\n\n // ------------------------------ DRAWING -------------------------------\n\n _renderSVG() {\n // BACKGROUND\n this._container.style('background-color', this._background)\n\n // BOUNDS\n this._gBound = this._container.append('g')\n .attr('transform', `translate(${this._marginLeft}, ${this._marginTop})`);\n\n // NODES\n this._svgNode = this._gBound\n .append('g')\n .attr('stroke', '#000')\n .selectAll('.sankey-node')\n .data(this._nodes, node => node.name)\n .join('rect')\n .attr('class', 'sankey-node')\n .attr('id', d => d.name)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('height', d => d.y1 - d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('stroke', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .attr('fill', d => {\n const colorArray = JSON.parse(this._colorArray);\n if (Object.keys(colorArray).includes(d.name)) {\n return colorArray[d.name];\n }\n return \"rgba(148, 153, 168, 1)\";\n })\n .on('mouseover', d => this._highlightOnHover && this._showLinks(d.target?.__data__))\n .on('mouseout', _ => this._highlightOnHover && this._showAll());\n\n // LINKS\n this._svgLink = this._gBound\n .append('g')\n .attr('fill', 'none')\n .attr('stroke-opacity', 0.3)\n .selectAll('g')\n .data(this._links, link => `${link.source.name}-${link.target.name}`)\n .join('g')\n .style('mix-blend-mode', 'multiply');\n\n if (this._edgeColor === 'path') this._setLinkGradient()\n\n this._svgLink\n .append('path')\n .attr('class', 'sankey-link')\n .attr('d', d3Sankey.sankeyLinkHorizontal())\n .attr('stroke', \"rgba(182, 185, 196, 1)\")\n .attr('stroke-width', d => Math.max(1, d.width)); \n\n // LABELS\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('y', d => (d.y1 + d.y0) / 2)\n .attr('dy', '0.35em')\n .text(d => d.name);\n\n this._gBound\n .append('g')\n .attr('font-family', 'sans-serif')\n .attr('font-size', 10)\n .selectAll('text')\n .data(this._nodes)\n .join('text')\n .attr('x', d => d.x0 + 8)\n .attr('font-size', 14)\n .attr('font-weight', '700')\n .attr('y', d => ((d.y1 + d.y0) / 2) + 16)\n .attr('dy', '0.35em')\n .text(d => this._labelNodeValue(d));\n\n this._svgNode\n .append('title')\n .text(d => `${d.name}\\n${this._formatValue(d.value)}`);\n\n this._svgLink\n .append('title')\n .text(d => `${d.source.name} → ${d.target.name}\\n${this._formatValue(d.value)}`);\n }\n\n\n // ----------------------------------------------------------------------- \n // ------------------------------ API ------------------------------\n // ----------------------------------------------------------------------- \n\n data(_) {\n return arguments.length ? (this._data = _, this) : this._data;\n };\n\n width(_) {\n return arguments.length ? (this._width = +_, this) : this._width;\n };\n\n height(_) {\n return arguments.length ? (this._height = +_, this) : this._height;\n };\n\n align(_) {\n return arguments.length ? (this._sankeyAlignType = _, this) : this._sankeyAlignType;\n }\n\n colorScheme(_) {\n return arguments.length ? (this._colorScheme = _, this) : this._colorScheme;\n }\n\n colorArray(_) {\n return arguments.length ? (this._colorArray = _, this) : this._colorArray;\n }\n\n edgeColor(_) {\n return arguments.length ? (this._edgeColor = _, this) : this._edgeColor;\n }\n\n displayValues(_) {\n return arguments.length ? (this._displayValues = _, this) : this._displayValues;\n }\n\n highlightOnHover(_) {\n return arguments.length ? (this._highlightOnHover = _, this) : this._highlightOnHover;\n }\n\n render() {\n if (!this._validate()) {\n // no graph data\n }\n else {\n this._init();\n this._renderSVG()\n }\n return this;\n }\n}\n","// @ts-nocheck\nimport React from 'react';\nimport { Icon } from '@grafana/ui';\n\nexport const ErrorMessage = ({ message }) => ( \n

\n

\n \n
{message}
\n
\n

\n)\n\nconst panelStyles = {\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n}\n\nconst containerStyles = {\n padding: '15px 20px',\n marginBottom: '4px',\n position: 'relative',\n color: 'rgb(255, 255, 255)',\n textShadow: 'rgb(0 0 0 / 20%) 0px 1px 0px',\n borderRadius: '3px',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n background: 'linear-gradient(90deg, rgb(224, 47, 68), rgb(224, 47, 68))'\n}\n\nconst messageStyles = {\n marginLeft: 10\n}\n","const SHOULD_LOG = true;\n\nexport const logger = fnLogger();\n\nfunction fnLogger(shouldLog = SHOULD_LOG) {\n if (!shouldLog) {\n return {\n warn: (..._: any[]) => undefined,\n error: (..._: any[]) => undefined,\n log: (..._: any[]) => undefined,\n };\n }\n\n return {\n warn: console.warn,\n error: console.error,\n log: console.log,\n };\n}\n","// @ts-nocheck\nimport React, { useState, useEffect } from 'react';\nimport * as d3 from 'd3';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyOptions } from 'types';\nimport { Sankey } from 'Sankey'\nimport { ErrorMessage } from 'Error'\nimport { logger } from 'fn-logger';\n\ninterface Props extends PanelProps {}\n\nexport const SankeyPanel: React.FC = ({ options, data, width, height }) => {\n // ------------------------ CHART CONSTANTS -----------------------\n const CHART_REQUIRED_FIELDS = { source: 'source', target: 'target', value: 'value' };\n\n // ------------------------ ERROR MESSAGES ------------------------\n const requiredFieldsMsg = `Required fields not present: ${Object.keys(CHART_REQUIRED_FIELDS).join(', ')}`;\n const fieldTypeMsg = `Fields should have the following types: source (string), target (string), value (numeric)`;\n\n // ------------------------- REACT HOOKS --------------------------\n const [ error, setError ] = useState({ isError: false, message: '' })\n const [ graph, setGraph ] = useState({ nodes: [], links: [] })\n\n useEffect(() => {\n if (data.error) {\n logger.warn('[FN] Sankey data error.',{data, error: data.error})\n }\n\n data.error\n ?\n setError({isError: true, message: data.error.message})\n :\n setGraph(buildGraph())\n }, [data])\n\n // ------------------------- DATA ACQUISITION -------------------------\n const validate = (sources, targets, values) => {\n let isValid = true;\n\n // REQUIRED FIELDS\n if (!(sources && targets && values)) {\n setError({ isError: true, message: requiredFieldsMsg })\n return isValid = false;\n }\n\n // FIELD TYPES\n const sourcesString = sources.every(d => typeof d === 'string')\n const targetsString = targets.every(d => typeof d === 'string')\n const valuesNumeric = values.every(d => typeof d === 'number')\n\n if (!(sourcesString && targetsString && valuesNumeric)) {\n setError({ isError: true, message: fieldTypeMsg })\n return isValid = false;\n }\n\n setError({});\n\n return isValid;\n }\n\n const buildGraph = () => {\n const frame = data.series[0];\n\n const sourceAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.source);\n const targetAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.target);\n const valueAccesor = frame.fields.find(field => field.name === CHART_REQUIRED_FIELDS.value);\n\n const sources = sourceAccesor?.values.toArray();\n const targets = targetAccesor?.values.toArray();\n const values = valueAccesor?.values.toArray();\n\n const isValid = validate(sources, targets, values);\n if (!isValid) {return}\n\n const zip = d3.zip(sources, targets, values);\n\n const nodes = Array.from(new Set(sources.concat(targets))).map(node => ({ name: node }));\n const links = zip.map(d => ({ source: d[0], target: d[1], value: +d[2].toFixed(2) }));\n const graph = { nodes, links };\n\n return graph\n }\n\n // ------------------------------- CHART ------------------------------\n const chart = svg => {\n const sankey = new Sankey(svg)\n .width(width)\n .height(height)\n .align(options.align)\n .edgeColor(options.edgeColor)\n .colorScheme(options.colorScheme)\n .displayValues(options.displayValues)\n .highlightOnHover(options.highlightOnHover)\n .colorArray(options.colorArray)\n .data(graph)\n\n try {\n sankey.render();\n } catch (renderError) {\n logger.warn('[FN] Sankey render error.',{renderError, graph})\n\n setError({isError: true, message: renderError.message})\n }\n };\n\n return (error.isError ?\n \n :\n {\n d3.select(node)\n .selectAll('*')\n .remove();\n d3.select(node).call(chart);\n }}\n />\n );\n};\n","// NOTE: implementation of toDataFrame: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/dataframe/processDataFrame.ts\nimport { toDataFrame, FieldType, ArrayVector, Field } from '@grafana/data';\nimport { logger } from 'fn-logger';\n\nimport { SankeyOptionsFn } from 'types-fn';\n\nexport function transformFnData(): Required['transformFn'] {\n return ({ series, ...other }) => {\n const transformedSeries = series.map((data) => {\n return toDataFrame({ ...data, fields: data.fields.map(mapField()) });\n });\n\n return {\n series: transformedSeries,\n ...other,\n };\n };\n}\n\nconst SANKEY_FIELD_NAMES = ['source', 'target', 'value'];\n\n// @ts-ignore\nfunction mapField

() {\n return (field: Field

, _: number, __: Array>) => {\n const isSankeyField = SANKEY_FIELD_NAMES.includes(field.name);\n\n const isArrayVector = field.values instanceof ArrayVector || typeof field.values?.toArray === 'function';\n const isArray = Array.isArray(field.values);\n\n if (!isSankeyField || !field.values || (!isArray && !isArrayVector)) {\n return field;\n }\n\n const values = isArrayVector ? field.values.toArray() : isArray ? field.values : null;\n\n if (values === null) {\n logger.warn('[FN] Failed to transform sankey data.', 'Values are not an array.');\n\n return {\n ...field,\n values: new ArrayVector([]),\n };\n }\n\n const parsedValues = isSankeyField ? ((values as P[]).map(splitValue())[0] as unknown[]).map(mapToNumber()) : null;\n\n try {\n return {\n ...field,\n type: parsedValues?.every(isNumber()) ? FieldType.number : field.type,\n values: parsedValues ? new ArrayVector(JSON.parse(JSON.stringify(parsedValues))) : values,\n };\n } catch (err) {\n logger.warn('[FN] Failed to transform sankey data.', err instanceof Error ? err.message : String(err));\n\n return {\n ...field,\n type: field.type,\n values: new ArrayVector([]),\n };\n }\n };\n}\n\n// @ts-ignore\nfunction mapToNumber() {\n return (value: V, _: number, __: V[]) => (Number.isNaN(Number(value)) ? value : Number(value));\n}\n\n// @ts-ignore\nfunction splitValue() {\n return (value: V) => (typeof value === 'string' ? value.split('|') : value);\n}\n\n// @ts-ignore\nfunction isNumber() {\n return (value: V) => typeof value === 'number';\n}\n","import { PanelPlugin } from '@grafana/data';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { SankeyPanelFn as SankeyPanel } from './SankeyPanelFn';\n\nexport const plugin = new PanelPlugin(SankeyPanel).setPanelOptions((builder) => {\n return builder\n .addSelect({\n path: 'align',\n name: 'Align',\n defaultValue: 'Justify',\n settings: {\n options: [\n {\n value: 'Justify',\n label: 'Justify',\n },\n {\n value: 'Left',\n label: 'Left',\n },\n {\n value: 'Right',\n label: 'Right',\n },\n {\n value: 'Center',\n label: 'Center',\n },\n ],\n },\n })\n .addTextInput({\n path: 'colorArray',\n name: 'Color Object',\n defaultValue: '',\n })\n .addSelect({\n path: 'colorScheme',\n name: 'Color',\n defaultValue: 'Tableau10',\n settings: {\n options: [\n {\n value: 'Tableau10',\n label: 'Tableau10',\n },\n {\n value: 'Category10',\n label: 'Category10',\n },\n {\n value: 'Accent',\n label: 'Accent',\n },\n {\n value: 'Dark2',\n label: 'Dark2',\n },\n {\n value: 'Paired',\n label: 'Paired',\n },\n {\n value: 'Pastel1',\n label: 'Pastel1',\n },\n {\n value: 'Pastel2',\n label: 'Pastel2',\n },\n {\n value: 'Set1',\n label: 'Set1',\n },\n {\n value: 'Set2',\n label: 'Set2',\n },\n {\n value: 'Set3',\n label: 'Set3',\n },\n ],\n },\n })\n .addSelect({\n path: 'edgeColor',\n name: 'Edge Color',\n defaultValue: 'path',\n settings: {\n options: [\n {\n value: 'path',\n label: 'input-output',\n },\n {\n value: 'input',\n label: 'input',\n },\n {\n value: 'output',\n label: 'output',\n },\n {\n value: 'none',\n label: 'none',\n },\n ],\n },\n })\n .addSelect({\n path: 'displayValues',\n name: 'Display Values',\n defaultValue: 'none',\n settings: {\n options: [\n {\n value: 'total',\n label: 'Totals',\n },\n {\n value: 'percentage',\n label: 'Percentages',\n },\n {\n value: 'both',\n label: 'Both',\n },\n {\n value: 'none',\n label: 'None',\n },\n ],\n },\n })\n .addBooleanSwitch({\n path: 'highlightOnHover',\n name: 'Highlight connections on node hover',\n defaultValue: false,\n });\n});\n","import React, { useMemo, FC } from 'react';\nimport { PanelProps } from '@grafana/data';\nimport { SankeyPanel } from 'SankeyPanel';\nimport { SankeyOptionsFn } from 'types-fn';\nimport { transformFnData } from 'transform-fn-data';\n\nexport interface SankeyPanelFnProps extends PanelProps {}\n\nexport const SankeyPanelFn: FC = ({ data, ...props }) => {\n const transformFn = useMemo(transformFnData, []);\n\n const transformedData = useMemo(() => transformFn(data), [transformFn, data]);\n\n return ;\n};\n"],"sourceRoot":""} \ No newline at end of file diff --git a/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json b/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json index 621bba580d282..1636445682417 100644 --- a/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json +++ b/public/app/plugins/panel/sankey-panel-0.5.0/plugin.json @@ -25,7 +25,7 @@ ], "screenshots": [], "version": "1.0.0", - "updated": "2023-01-05" + "updated": "2023-10-19" }, "dependencies": { "grafanaVersion": "7.0.x", diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index faf617da88e6a..6b4bb8a0c5584 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -27,7 +27,7 @@ From d47ffa66c9b772a82f108d08f5800acc4d77beb0 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Thu, 19 Oct 2023 20:51:03 -0400 Subject: [PATCH 070/101] confirm grafana initialization (#107) * window event to confirm initialization * grafana start up status events --- public/app/fn_app.ts | 167 +++++++++++++++++++++++++++++++++---------- 1 file changed, 131 insertions(+), 36 deletions(-) diff --git a/public/app/fn_app.ts b/public/app/fn_app.ts index 37054857c68d5..79301e66c9916 100644 --- a/public/app/fn_app.ts +++ b/public/app/fn_app.ts @@ -1,13 +1,14 @@ +import 'symbol-observable'; import 'core-js'; import 'regenerator-runtime/runtime'; -import 'symbol-observable'; -import 'file-saver'; -import 'jquery'; import 'whatwg-fetch'; // fetch polyfill needed for PhantomJs rendering import './polyfills/old-mediaquerylist'; // Safari < 14 does not have mql.addEventListener() +import 'file-saver'; +import 'jquery'; import 'app/features/all'; + import _ from 'lodash'; // eslint-disable-line lodash/import-scope import { @@ -28,9 +29,15 @@ import { setEchoSrv, setLocationSrv, setQueryRunnerFactory, + setRunRequest, + setPluginImportUtils, + setPluginExtensionGetter, + setAppEvents, + type GetPluginExtensions, } from '@grafana/runtime'; import { setPanelDataErrorView } from '@grafana/runtime/src/components/PanelDataErrorView'; import { setPanelRenderer } from '@grafana/runtime/src/components/PanelRenderer'; +import { setPluginPage } from '@grafana/runtime/src/components/PluginPage'; import { getScrollbarWidth } from '@grafana/ui'; import config, { Settings } from 'app/core/config'; import { arrayMove } from 'app/core/utils/arrayMove'; @@ -38,9 +45,12 @@ import { getStandardTransformers } from 'app/features/transformers/standardTrans import getDefaultMonacoLanguages from '../lib/monaco-languages'; +import appEvents from './core/app_events'; import { AppChromeService } from './core/components/AppChrome/AppChromeService'; import { getAllOptionEditors, getAllStandardFieldConfigs } from './core/components/OptionsUI/registry'; +import { PluginPage } from './core/components/Page/PluginPage'; import { GrafanaContextType } from './core/context/GrafanaContext'; +import { initializeI18n } from './core/internationalization'; import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks'; import { ModalManager } from './core/services/ModalManager'; import { backendSrv } from './core/services/backend_srv'; @@ -49,18 +59,25 @@ import { Echo } from './core/services/echo/Echo'; import { reportPerformance } from './core/services/echo/EchoSrv'; import { PerformanceBackend } from './core/services/echo/backends/PerformanceBackend'; import { ApplicationInsightsBackend } from './core/services/echo/backends/analytics/ApplicationInsightsBackend'; -import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend'; +// import { GA4EchoBackend } from './core/services/echo/backends/analytics/GA4Backend'; +// import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend'; import { RudderstackBackend } from './core/services/echo/backends/analytics/RudderstackBackend'; import { GrafanaJavascriptAgentBackend } from './core/services/echo/backends/grafana-javascript-agent/GrafanaJavascriptAgentBackend'; -import { SentryEchoBackend } from './core/services/echo/backends/sentry/SentryBackend'; -import { initializeI18n } from './core/internationalization'; +import { KeybindingSrv } from './core/services/keybindingSrv'; +import { startMeasure, stopMeasure } from './core/utils/metrics'; import { initDevFeatures } from './dev'; import { getTimeSrv } from './features/dashboard/services/TimeSrv'; +// import { initGrafanaLive } from './features/live'; import { PanelDataErrorView } from './features/panel/components/PanelDataErrorView'; import { PanelRenderer } from './features/panel/components/PanelRenderer'; import { DatasourceSrv } from './features/plugins/datasource_srv'; +import { createPluginExtensionRegistry } from './features/plugins/extensions/createPluginExtensionRegistry'; +import { getCoreExtensionConfigurations } from './features/plugins/extensions/getCoreExtensionConfigurations'; +import { getPluginExtensions } from './features/plugins/extensions/getPluginExtensions'; +import { importPanelPlugin, syncGetPanelPlugin } from './features/plugins/importPanelPlugin'; import { preloadPlugins } from './features/plugins/pluginPreloader'; import { QueryRunner } from './features/query/state/QueryRunner'; +import { runRequest } from './features/query/state/runRequest'; import { initWindowRuntime } from './features/runtime/init'; import { variableAdapters } from './features/variables/adapters'; import { createAdHocVariableAdapter } from './features/variables/adhoc/adapter'; @@ -73,7 +90,7 @@ import { setVariableQueryRunner, VariableQueryRunner } from './features/variable import { createQueryVariableAdapter } from './features/variables/query/adapter'; import { createSystemVariableAdapter } from './features/variables/system/adapter'; import { createTextBoxVariableAdapter } from './features/variables/textbox/adapter'; -import { ConfiguredStore, configureStore } from './store/configureStore'; +import { configureStore } from './store/configureStore'; // add move to lodash for backward compatabilty with plugins // @ts-ignore @@ -89,16 +106,42 @@ if (process.env.NODE_ENV === 'development') { initDevFeatures(); } +export declare type FNGrafanaStartupState = { + isLoading: boolean; + isError: boolean; + error?: unknown; + isIdeal: boolean; +}; + +export const DefaultGrafanaStartupState: FNGrafanaStartupState = { + isLoading: false, + isError: false, + isIdeal: true, +}; + +const dispatchFnEvent = (info: FNGrafanaStartupState = DefaultGrafanaStartupState, ek = 'grafana-startup') => { + window.dispatchEvent( + new CustomEvent(ek, { + detail: info, + }) + ); +}; + export class GrafanaApp { context!: GrafanaContextType; - readonly store: ConfiguredStore; - - constructor() { - this.store = configureStore(); - } async init() { try { + dispatchFnEvent({ + isIdeal: false, + isLoading: true, + isError: false, + }); + // Let iframe container know grafana has started loading + parent.postMessage('GrafanaAppInit', '*'); + + const initI18nPromise = initializeI18n(config.bootData.user.language); + backendSrv.setGrafanaPrefix(true); setBackendSrv(backendSrv); const settings: Settings = await backendSrv.get('/api/frontend/settings'); @@ -107,18 +150,28 @@ export class GrafanaApp { config.datasources = settings.datasources; config.defaultDatasource = settings.defaultDatasource; - initializeI18n(config.bootData.user.locale); - initEchoSrv(); + // This needs to be done after the `initEchoSrv` since it is being used under the hood. + startMeasure('frontend_app_init'); addClassIfNoOverlayScrollbar(); setLocale(config.bootData.user.locale); setWeekStart(config.bootData.user.weekStart); setPanelRenderer(PanelRenderer); + setPluginPage(PluginPage); setPanelDataErrorView(PanelDataErrorView); setLocationSrv(locationService); setTimeZoneResolver(() => config.bootData.user.timezone); + // initGrafanaLive(); + + // Expose the app-wide eventbus + setAppEvents(appEvents); + + // We must wait for translations to load because some preloaded store state requires translating + await initI18nPromise; + // Important that extension reducers are initialized before store addExtensionReducers(); + configureStore(); initExtensions(); standardEditorsRegistry.setInit(getAllOptionEditors); @@ -139,6 +192,15 @@ export class GrafanaApp { setQueryRunnerFactory(() => new QueryRunner()); setVariableQueryRunner(new VariableQueryRunner()); + // Provide runRequest implementation to packages, @grafana/scenes in particular + setRunRequest(runRequest); + + // Privide plugin import utils to packages, @grafana/scenes in particular + setPluginImportUtils({ + importPanelPlugin, + getPanelPluginFromCache: syncGetPanelPlugin, + }); + locationUtil.initialize({ config, getTimeRangeForUrl: getTimeSrv().timeRangeForUrl, @@ -159,20 +221,52 @@ export class GrafanaApp { modalManager.init(); // Preload selected app plugins - await preloadPlugins(config.pluginsToPreload); + const preloadResults = await preloadPlugins(config.apps); + + // Create extension registry out of preloaded plugins and core extensions + const extensionRegistry = createPluginExtensionRegistry([ + { pluginId: 'grafana', extensionConfigs: getCoreExtensionConfigurations() }, + ...preloadResults, + ]); + + // Expose the getPluginExtension function via grafana-runtime + const pluginExtensionGetter: GetPluginExtensions = (options) => + getPluginExtensions({ ...options, registry: extensionRegistry }); + + setPluginExtensionGetter(pluginExtensionGetter); + + // initialize chrome service + const queryParams = locationService.getSearchObject(); + const chromeService = new AppChromeService(); + const keybindingsService = new KeybindingSrv(locationService, chromeService); + + // Read initial kiosk mode from url at app startup + chromeService.setKioskModeFromUrl(queryParams.kiosk); this.context = { backend: backendSrv, location: locationService, - chrome: new AppChromeService(), + chrome: chromeService, + keybindings: keybindingsService, config, }; + + dispatchFnEvent({ + isLoading: false, + isError: false, + isIdeal: false, + }); } catch (error) { + dispatchFnEvent({ + isLoading: false, + isError: true, + error, + isIdeal: false, + }); console.error('Failed to start Grafana', error); - - if (window.__grafana_load_failed) { - window.__grafana_load_failed(); - } + window.__grafana_load_failed(); + } finally { + stopMeasure('frontend_app_init'); } } } @@ -212,15 +306,6 @@ function initEchoSrv() { registerEchoBackend(new PerformanceBackend({})); } - if (config.sentry.enabled) { - registerEchoBackend( - new SentryEchoBackend({ - ...config.sentry, - user: config.bootData.user, - buildInfo: config.buildInfo, - }) - ); - } if (config.grafanaJavascriptAgent.enabled) { registerEchoBackend( new GrafanaJavascriptAgentBackend({ @@ -238,13 +323,22 @@ function initEchoSrv() { ); } - if (config.googleAnalyticsId) { - registerEchoBackend( - new GAEchoBackend({ - googleAnalyticsId: config.googleAnalyticsId, - }) - ); - } + // if (config.googleAnalyticsId) { + // registerEchoBackend( + // new GAEchoBackend({ + // googleAnalyticsId: config.googleAnalyticsId, + // }) + // ); + // } + + // if (config.googleAnalytics4Id) { + // registerEchoBackend( + // new GA4EchoBackend({ + // googleAnalyticsId: config.googleAnalytics4Id, + // googleAnalytics4SendManualPageViews: config.googleAnalytics4SendManualPageViews, + // }) + // ); + // } if (config.rudderstackWriteKey && config.rudderstackDataPlaneUrl) { registerEchoBackend( @@ -254,6 +348,7 @@ function initEchoSrv() { user: config.bootData.user, sdkUrl: config.rudderstackSdkUrl, configUrl: config.rudderstackConfigUrl, + buildInfo: config.buildInfo, }) ); } From b4b48436d54d2844ff1d27e633dbd0c04a77988a Mon Sep 17 00:00:00 2001 From: Jaseel <12792882+Spikatrix@users.noreply.github.com> Date: Wed, 1 Nov 2023 23:38:36 +0530 Subject: [PATCH 071/101] Show filters icon only when there are some variables to show (#116) --- .../dashboard/components/SubMenu/SubMenu.tsx | 74 +++++++------------ .../components/SubMenu/SubMenuItems.tsx | 32 ++++++-- 2 files changed, 52 insertions(+), 54 deletions(-) diff --git a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx index d864104bdc7e6..9f209f471ddd3 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx @@ -1,21 +1,18 @@ import { css } from '@emotion/css'; -import FilterListIcon from '@mui/icons-material/FilterList'; -import { Box, styled } from '@mui/material'; -import React, { FC, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; import { connect, MapStateToProps } from 'react-redux'; -import { AnnotationQuery, DataQuery, TypedVariableModel, GrafanaTheme2 } from '@grafana/data'; -import { FnGlobalState } from 'app/core/reducers/fn-slice'; +import { AnnotationQuery, DataQuery, GrafanaTheme2 } from '@grafana/data'; +import { stylesFactory, Themeable2, withTheme2 } from '@grafana/ui'; import { StoreState } from '../../../../types'; import { getSubMenuVariables, getVariablesState } from '../../../variables/state/selectors'; +import { VariableModel } from '../../../variables/types'; import { DashboardModel } from '../../state'; import { Annotations } from './Annotations'; import { DashboardLinks } from './DashboardLinks'; import { SubMenuItems } from './SubMenuItems'; -// import { VariableModel } from 'app/features/variables/types'; -import { Themeable2, stylesFactory, withTheme2 } from '@grafana-ui'; import { DashboardLink } from '@grafana/schema/dist/esm/index'; interface OwnProps extends Themeable2 { @@ -25,8 +22,7 @@ interface OwnProps extends Themeable2 { } interface ConnectedProps { - variables: TypedVariableModel[]; - hiddenVariables: FnGlobalState['hiddenVariables']; + variables: VariableModel[]; } interface DispatchProps {} @@ -56,17 +52,16 @@ class SubMenuUnConnected extends PureComponent { const styles = getStyles(theme); + if (!dashboard.isSubMenuVisible()) { + return null; + } + const readOnlyVariables = dashboard.meta.isSnapshot ?? false; return ( -

- - - +
+ + = ( return { variables: getSubMenuVariables(uid, templatingState.variables), - hiddenVariables: state.fnGlobalState.hiddenVariables, }; }; const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { - formStyles: css({ - display: 'contents', - flexWrap: 'wrap', - }), - submenu: css({ - display: 'flex', - flexDirection: 'row', - flexWrap: 'wrap', - alignContent: 'flex-start', - alignItems: 'flex-start', - gap: `${theme.spacing(1)} ${theme.spacing(2)}`, - padding: `0 0 ${theme.spacing(1)} 0`, - }), + formStyles: css` + display: flex; + flex-wrap: wrap; + display: contents; + `, + submenu: css` + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-content: flex-start; + align-items: flex-start; + gap: ${theme.spacing(1)} ${theme.spacing(2)}; + padding: 0 0 ${theme.spacing(1)} 0; + `, spacer: css({ flexGrow: 1, }), @@ -114,20 +109,3 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => { export const SubMenu = withTheme2(connect(mapStateToProps)(SubMenuUnConnected)); SubMenu.displayName = 'SubMenu'; - -const FilterWithIcon: FC = () => ( - - - FILTERS - -); - -const FilterWithIconStyled = styled(Box)({ - display: 'flex', - gap: 1, - alignItems: 'center', - color: '#3A785E', - fontWeight: 600, - lineHeight: '160%', - fontSize: 12, -}); diff --git a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx index 6c1256e5371c9..9200b4cf45326 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx @@ -1,21 +1,26 @@ -import React, { useEffect, useState } from 'react'; +import { css } from '@emotion/css'; +import { useEffect, useState } from 'react'; +import { GrafanaTheme2, TypedVariableModel, VariableHide } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { useSelector } from 'app/types'; +import { useStyles2 } from '@grafana/ui'; import { PickerRenderer } from '../../../variables/pickers/PickerRenderer'; -import { VariableHide, VariableModel } from '../../../variables/types'; +import { useSelector } from 'app/types'; interface Props { - variables: VariableModel[]; + variables: TypedVariableModel[]; readOnly?: boolean; } + export const SubMenuItems = ({ variables, readOnly }: Props) => { - const [visibleVariables, setVisibleVariables] = useState([]); + const [visibleVariables, setVisibleVariables] = useState([]); const hiddenVariables = useSelector((state) => state.fnGlobalState.hiddenVariables); + const styles = useStyles2(getStyles); + useEffect(() => { setVisibleVariables( variables.filter((state) => state.hide !== VariableHide.hideVariable && !hiddenVariables?.includes(state.id)) @@ -32,7 +37,7 @@ export const SubMenuItems = ({ variables, readOnly }: Props) => { return (
@@ -42,3 +47,18 @@ export const SubMenuItems = ({ variables, readOnly }: Props) => { ); }; + +const getStyles = (theme: GrafanaTheme2) => ({ + submenuItem: css({ + display: 'inline-block', + + '.fa-caret-down': { + fontSize: '75%', + paddingLeft: theme.spacing(1), + }, + + '.gf-form': { + marginBottom: 0, + }, + }), +}); From 819b0ba528c9e8e55f662d086809a4990801b835 Mon Sep 17 00:00:00 2001 From: Krzysztof Kwapisiewicz Date: Wed, 8 Nov 2023 13:14:39 +0100 Subject: [PATCH 072/101] Don't panic on empty var Druid query (#123) --- pkg/tsdb/druid/column_type.go | 4 ++++ pkg/tsdb/druid/druid.go | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pkg/tsdb/druid/column_type.go b/pkg/tsdb/druid/column_type.go index 20433d84ec1e9..d29f9b9738c5f 100644 --- a/pkg/tsdb/druid/column_type.go +++ b/pkg/tsdb/druid/column_type.go @@ -7,6 +7,10 @@ import ( ) func detectColumnType(c *responseColumn, pos int, rows [][]interface{}) { + if len(rows) == 0 { + c.Type = ColumnString + return + } t := map[columnType]int{"nil": 0} maxRowsToScan := (len(rows) / 5) + 1 for _, row := range rows[:maxRowsToScan] { diff --git a/pkg/tsdb/druid/druid.go b/pkg/tsdb/druid/druid.go index bd78dfeca233a..c8dac6f206af9 100644 --- a/pkg/tsdb/druid/druid.go +++ b/pkg/tsdb/druid/druid.go @@ -608,8 +608,11 @@ func (ds *Service) oldExecuteQuery(queryRef string, q druidquerybuilder.Query, s err := json.Unmarshal(res, &tn) if err == nil && len(tn) > 0 { columns := []string{"timestamp"} - for c := range tn[0]["result"].([]interface{})[0].(map[string]interface{}) { - columns = append(columns, c) + results := tn[0]["result"].([]interface{}) + if len(results) > 0 { + for c := range results[0].(map[string]interface{}) { + columns = append(columns, c) + } } for _, result := range tn { for _, record := range result["result"].([]interface{}) { From 32adca581efc69150d61de096549a70ed7b344d5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kwapisiewicz Date: Wed, 8 Nov 2023 13:27:20 +0100 Subject: [PATCH 073/101] Remove not needed GH Actions (#124) --- .../ephemeral-instances-pr-comment.yml | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 .github/workflows/ephemeral-instances-pr-comment.yml diff --git a/.github/workflows/ephemeral-instances-pr-comment.yml b/.github/workflows/ephemeral-instances-pr-comment.yml deleted file mode 100644 index be07b7ef6acab..0000000000000 --- a/.github/workflows/ephemeral-instances-pr-comment.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: 'Ephemeral instances' -on: - issue_comment: - types: [created] - pull_request: - types: [closed] -jobs: - config: - runs-on: "ubuntu-latest" - outputs: - has-secrets: ${{ steps.check.outputs.has-secrets }} - steps: - - name: "Check for secrets" - id: check - shell: bash - run: | - if [ -n "${{ (secrets.EI_APP_ID != '' && - secrets.EI_APP_PRIVATE_KEY != '' && - secrets.EI_GCOM_HOST != '' && - secrets.EI_GCOM_TOKEN != '' && - secrets.EI_EPHEMERAL_INSTANCES_REGISTRY != '' && - secrets.EI_GCP_SERVICE_ACCOUNT_KEY_BASE64 != '' && - secrets.EI_EPHEMERAL_ORG_ID != '' - ) || '' }}" ]; then - echo "has-secrets=1" >> "$GITHUB_OUTPUT" - fi - - handle-pull-request-event: - needs: config - if: needs.config.outputs.has-secrets && - ${{ github.event.issue.pull_request && (startsWith(github.event.comment.body, '/deploy-to-hg') || github.event.action == 'closed') }} - runs-on: - labels: ubuntu-latest-8-cores - continue-on-error: true - steps: - - name: Generate a GitHub app installation token - id: generate_token - uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 - with: - app_id: ${{ secrets.EI_APP_ID }} - private_key: ${{ secrets.EI_APP_PRIVATE_KEY }} - - - name: Checkout ephemeral instances repository - uses: actions/checkout@v4 - with: - repository: grafana/ephemeral-grafana-instances-github-action - token: ${{ steps.generate_token.outputs.token }} - ref: main - path: ephemeral - - - name: build and deploy ephemeral instance - uses: ./ephemeral - with: - github-token: ${{ steps.generate_token.outputs.token }} - gcom-host: ${{ secrets.EI_GCOM_HOST }} - gcom-token: ${{ secrets.EI_GCOM_TOKEN }} - registry: "${{ secrets.EI_EPHEMERAL_INSTANCES_REGISTRY }}" - gcp-service-account-key: "${{ secrets.EI_GCP_SERVICE_ACCOUNT_KEY_BASE64 }}" - ephemeral-org-id: "${{ secrets.EI_EPHEMERAL_ORG_ID }}" - oss-or-enterprise: oss - verbose: true From dd2193781dfcb014dcb4ea5554d391dd020b7496 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Mon, 11 Dec 2023 16:28:39 -0500 Subject: [PATCH 074/101] changed to cirular progress (#148) * changed to cirular progress * codeRabbit suggestions --- .../components/DashboardLoading/FnLoader.tsx | 17 +++++----- .../DashboardLoading/fn-lottie-loader.json | 1 - public/app/fn-app/fn-app-provider.tsx | 22 ++++--------- yarn.lock | 31 ------------------- 4 files changed, 14 insertions(+), 57 deletions(-) delete mode 100644 public/app/features/dashboard/components/DashboardLoading/fn-lottie-loader.json diff --git a/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx b/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx index 06e89d319d295..751ae08e747ca 100644 --- a/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx +++ b/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx @@ -1,14 +1,12 @@ -import { Box, Typography, type BoxProps } from '@mui/material'; -import Lottie, { type LottieComponentProps } from 'lottie-react'; +import { Box, CircularProgress, CircularProgressProps, Typography, type BoxProps } from '@mui/material'; import React, { type ReactNode, type FC, type HTMLAttributes } from 'react'; import logoUrl from './fn-logo.svg'; -import logoLoader from './fn-lottie-loader.json'; export type FnLoaderProps = { outerContainerProps?: Omit; innerContainerProps?: Omit; - lottieProps?: LottieComponentProps; + circularProgressProps?: CircularProgressProps; imageProps?: HTMLAttributes; text?: ReactNode; }; @@ -16,7 +14,7 @@ export type FnLoaderProps = { export const FnLoader: FC = ({ outerContainerProps, innerContainerProps, - lottieProps, + circularProgressProps, imageProps, text, }) => ( @@ -30,11 +28,12 @@ export const FnLoader: FC = ({ > {'FluxNinja - {typeof text === 'string' ? {text} : text || null} diff --git a/public/app/features/dashboard/components/DashboardLoading/fn-lottie-loader.json b/public/app/features/dashboard/components/DashboardLoading/fn-lottie-loader.json deleted file mode 100644 index de88f090df070..0000000000000 --- a/public/app/features/dashboard/components/DashboardLoading/fn-lottie-loader.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.9.3","fr":29.9700012207031,"ip":0,"op":81.0000032991976,"w":1080,"h":1080,"nm":"Dots loader 14","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":" - Group 2 - Group 2 - Group 15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-80,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-40,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":0,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":40,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":80,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":120,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":160,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":200,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":240,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":280,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":320,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":360,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":400,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":440,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":480,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":520,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":560,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":600,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":640,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":680,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":720,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":760,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":800,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":840,"s":[540.019,150.048,0],"to":[0,0,0],"ti":[0,0,0]},{"t":880.000035843135,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-80,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-40,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":40,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":80,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":120,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":160,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":200,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":240,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":280,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":320,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":360,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":400,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":440,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":480,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":520,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":560,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":600,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":640,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":680,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":720,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":760,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":800,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":840,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":880,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":920,"s":[620.85,620.85,100]},{"t":960.000039101602,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-80.0000032584668,"op":1415.00005763413,"st":-80.0000032584668,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":" - Group 2 - Group 2 - Group 27","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":22,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-90,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-50,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-10,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":30,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":70,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":110,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":150,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":190,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":230,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":270,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":310,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":350,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":390,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":430,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":470,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":510,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":550,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":590,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":630,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":670,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":710,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":750,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":790,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":830,"s":[685.581,179.364,0],"to":[0,0,0],"ti":[0,0,0]},{"t":870.000035435826,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-90,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-50,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-10,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":30,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":70,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":110,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":150,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":190,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":230,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":270,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":310,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":350,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":390,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":430,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":470,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":510,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":550,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":590,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":630,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":670,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":710,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":750,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":790,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":830,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":870,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":910,"s":[620.85,620.85,100]},{"t":950.000038694293,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-90.0000036657751,"op":1405.00005722682,"st":-90.0000036657751,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":" - Group 2 - Group 2 - Group 13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-100,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-60,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-20,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":20,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":60,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":100,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":140,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":180,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":220,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":260,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":300,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":340,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":380,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":420,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":460,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":500,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":540,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":580,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":620,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":660,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":700,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":740,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":780,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":820,"s":[814.372,265.866,0],"to":[0,0,0],"ti":[0,0,0]},{"t":860.000035028518,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-100,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-60,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-20,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":20,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":60,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":100,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":140,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":180,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":220,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":260,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":300,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":340,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":380,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":420,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":460,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":500,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":540,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":580,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":620,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":660,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":700,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":740,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":780,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":820,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":860,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":900,"s":[620.85,620.85,100]},{"t":940.000038286985,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-100.000004073084,"op":1395.00005681951,"st":-100.000004073084,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":" - Group 2 - Group 2 - Group 25","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":67,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-110,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-70,"s":[896.571,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-30,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":10,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":50,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":90,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":130,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":170,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":210,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":250,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":290,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":330,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":370,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":410,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":450,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":490,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":530,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":570,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":610,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":650,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":690,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":730,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":770,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":810,"s":[896.57,389.523,0],"to":[0,0,0],"ti":[0,0,0]},{"t":850.00003462121,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-110,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-70,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-30,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":10,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":50,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":90,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":130,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":170,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":210,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":250,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":330,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":370,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":410,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":450,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":490,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":530,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":570,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":610,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":650,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":690,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":730,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":770,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":810,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":850,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":890,"s":[620.85,620.85,100]},{"t":930.000037879677,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-110.000004480392,"op":1385.00005641221,"st":-110.000004480392,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":" - Group 2 - Group 2 - Group 19","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-120,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-80,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-40,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":0,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":40,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":80,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":120,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":160,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":200,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":240,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":280,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":320,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":360,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":400,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":440,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":480,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":520,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":560,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":600,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":640,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":680,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":720,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":760,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":800,"s":[926.474,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"t":840.000034213901,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-120,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-80,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-40,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":0,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":40,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":80,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":120,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":160,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":200,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":240,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":280,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":320,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":360,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":400,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":440,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":480,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":520,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":560,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":600,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":640,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":680,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":720,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":760,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":800,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":840,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":880,"s":[620.85,620.85,100]},{"t":920.000037472368,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-120.0000048877,"op":1375.0000560049,"st":-120.0000048877,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":" - Group 2 - Group 2 - Group 23","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":112,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-130,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-90,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-50,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-10,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":30,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":70,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":110,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":150,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":190,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":230,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":270,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":310,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":350,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":390,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":430,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":470,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":510,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":550,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":590,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":630,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":670,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":710,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":750,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":790,"s":[897.158,687.32,0],"to":[0,0,0],"ti":[0,0,0]},{"t":830.000033806593,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-130,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-90,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-50,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-10,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":70,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":110,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":150,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":190,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":230,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":270,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":310,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":350,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":390,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":430,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":470,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":510,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":550,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":590,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":630,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":670,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":710,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":750,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":790,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":830,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":870,"s":[620.85,620.85,100]},{"t":910.00003706506,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-130.000005295009,"op":1365.00005559759,"st":-130.000005295009,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":" - Group 2 - Group 2 - Group 17","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":135,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-140,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-100,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-60,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-20,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":20,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":60,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":100,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":140,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":180,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":220,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":260,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":300,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":340,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":380,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":420,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":460,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":500,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":540,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":580,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":620,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":660,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":700,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":740,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":780,"s":[810.656,816.112,0],"to":[0,0,0],"ti":[0,0,0]},{"t":820.000033399285,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-140,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-100,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-60,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-20,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":20,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":60,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":100,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":140,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":180,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":220,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":300,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":340,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":380,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":420,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":460,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":500,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":540,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":580,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":620,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":660,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":700,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":740,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":780,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":820,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":860,"s":[620.85,620.85,100]},{"t":900.000036657751,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-140.000005702317,"op":1355.00005519028,"st":-140.000005702317,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":" - Group 2 - Group 2 - Group 21","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":157,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-150,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-110,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-70,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-30,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":10,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":50,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":90,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":130,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":170,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":210,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":250,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":290,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":330,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":370,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":410,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":450,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":490,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":530,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":570,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":610,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":650,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":690,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":730,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":770,"s":[686.999,898.31,0],"to":[0,0,0],"ti":[0,0,0]},{"t":810.000032991976,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-150,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-110,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-70,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-30,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":10,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":50,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":90,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":130,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":170,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":210,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":250,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":290,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":330,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":370,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":410,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":450,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":490,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":530,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":570,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":610,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":650,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":690,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":730,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":770,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":810,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":850,"s":[620.85,620.85,100]},{"t":890.000036250443,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-150.000006109625,"op":1345.00005478297,"st":-150.000006109625,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":" - Group 2 - Group 2 - Group 16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-160,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-120,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-80,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-40,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":0,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":40,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":80,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":120,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":160,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":200,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":240,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":280,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":320,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":360,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":400,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":440,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":480,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":520,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":560,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":600,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":640,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":680,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":720,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":760,"s":[540.019,928.36,0],"to":[0,0,0],"ti":[0,0,0]},{"t":800.000032584668,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-160,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-120,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-80,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-40,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":40,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":80,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":120,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":160,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":200,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":240,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":280,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":320,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":360,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":400,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":440,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":480,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":520,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":560,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":600,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":640,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":680,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":720,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":760,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":800,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":840,"s":[620.85,620.85,100]},{"t":880.000035843135,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-160.000006516934,"op":1335.00005437566,"st":-160.000006516934,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":" - Group 2 - Group 2 - Group 28","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":22,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-170,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-130,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-90,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-50,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-10,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":30,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":70,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":110,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":150,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":190,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":230,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":270,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":310,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":350,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":390,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":430,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":470,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":510,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":550,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":590,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":630,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":670,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":710,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":750,"s":[394.02,901.003,0],"to":[0,0,0],"ti":[0,0,0]},{"t":790.00003217736,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-170,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-130,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-90,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-50,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-10,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":30,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":70,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":110,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":150,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":190,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":230,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":270,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":310,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":350,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":390,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":430,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":470,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":510,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":550,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":590,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":630,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":670,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":710,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":750,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":790,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":830,"s":[620.85,620.85,100]},{"t":870.000035435826,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-170.000006924242,"op":1325.00005396836,"st":-170.000006924242,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":" - Group 2 - Group 2 - Group 14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-180,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-140,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-100,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-60,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-20,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":20,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":60,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":100,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":140,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":180,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":220,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":260,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":300,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":340,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":380,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":420,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":460,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":500,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":540,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":580,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":620,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":660,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":700,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":740,"s":[264.022,816.216,0],"to":[0,0,0],"ti":[0,0,0]},{"t":780.000031770051,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-180,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-140,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-100,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-60,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-20,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":20,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":60,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":100,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":140,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":180,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":220,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":260,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":300,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":340,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":380,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":420,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":460,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":500,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":540,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":580,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":620,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":660,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":700,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":740,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":780,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":820,"s":[620.85,620.85,100]},{"t":860.000035028518,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-180.00000733155,"op":1315.00005356105,"st":-180.00000733155,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":" - Group 2 - Group 2 - Group 26","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":67,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-190,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-150,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-110,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-70,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-30,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":10,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":50,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":90,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":130,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":170,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":210,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":250,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":290,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":330,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":370,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":410,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":450,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":490,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":530,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":570,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":610,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":650,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":690,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":730,"s":[180.13,693.634,0],"to":[0,0,0],"ti":[0,0,0]},{"t":770.000031362743,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-190,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-150,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-110,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-70,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-30,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":10,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":50,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":90,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":130,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":170,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":210,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":250,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":330,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":370,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":410,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":450,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":490,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":530,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":570,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":610,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":650,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":690,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":730,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":770,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":810,"s":[620.85,620.85,100]},{"t":850.00003462121,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-190.000007738859,"op":1305.00005315374,"st":-190.000007738859,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":" - Group 2 - Group 2 - Group 20","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-200,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-160,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-120,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-80,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-40,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":0,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":40,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":80,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":120,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":160,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":200,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":240,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":280,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":320,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":360,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":400,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":440,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":480,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":520,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":560,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":600,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":640,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":680,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":720,"s":[148.161,541.758,0],"to":[0,0,0],"ti":[0,0,0]},{"t":760.000030955435,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-200,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-160,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-120,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-80,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-40,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":0,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":40,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":80,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":120,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":160,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":200,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":240,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":280,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":320,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":360,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":400,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":440,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":480,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":520,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":560,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":600,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":640,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":680,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":720,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":760,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":800,"s":[620.85,620.85,100]},{"t":840.000034213901,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-200.000008146167,"op":1295.00005274643,"st":-200.000008146167,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":" - Group 2 - Group 2 - Group 24","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":112,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-210,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-170,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-130,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-90,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-50,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-10,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":30,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":70,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":110,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":150,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":190,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":230,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":270,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":310,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":350,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":390,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":430,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":470,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":510,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":550,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":590,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":630,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":670,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":710,"s":[175.519,395.759,0],"to":[0,0,0],"ti":[0,0,0]},{"t":750.000030548126,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-210,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-170,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-130,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-90,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-50,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-10,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":70,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":110,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":150,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":190,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":230,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":270,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":310,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":350,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":390,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":430,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":470,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":510,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":550,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":590,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":630,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":670,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":710,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":750,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":790,"s":[620.85,620.85,100]},{"t":830.000033806593,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-210.000008553475,"op":1285.00005233912,"st":-210.000008553475,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":" - Group 2 - Group 2 - Group 18","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":135,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-220,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-180,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-140,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-100,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-60,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-20,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":20,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":60,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":100,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":140,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":180,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":220,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":260,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":300,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":340,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":380,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":420,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":460,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":500,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":540,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":580,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":620,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":660,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":700,"s":[260.306,265.762,0],"to":[0,0,0],"ti":[0,0,0]},{"t":740.000030140818,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-220,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-180,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-140,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-100,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-60,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-20,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":20,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":60,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":100,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":140,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":180,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":220,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":300,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":340,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":380,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":420,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":460,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":500,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":540,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":580,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":620,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":660,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":700,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":740,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":780,"s":[620.85,620.85,100]},{"t":820.000033399285,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-220.000008960784,"op":1275.00005193181,"st":-220.000008960784,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":" - Group 2 - Group 2 - Group 22","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":157,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-230,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-190,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-150,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-110,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-70,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":-30,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":10,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":50,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":90,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":130,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":170,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":210,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":250,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":290,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":330,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":370,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":410,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":450,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":490,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":530,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":570,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":610,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":650,"s":[537.681,540.791,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.58,"y":1},"o":{"x":0.42,"y":0},"t":690,"s":[382.888,181.869,0],"to":[0,0,0],"ti":[0,0,0]},{"t":730.00002973351,"s":[537.681,540.791,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-1030.724,-901.891,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-230,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-190,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-150,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-110,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-70,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":-30,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":10,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":50,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":90,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":130,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":170,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":210,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":250,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":290,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":330,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":370,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":410,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":450,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":490,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":530,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":570,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":610,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":650,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":690,"s":[620.85,620.85,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":730,"s":[0,0,100]},{"i":{"x":[0.58,0.58,0.58],"y":[1,1,1]},"o":{"x":[0.42,0.42,0.42],"y":[0,0,0]},"t":770,"s":[620.85,620.85,100]},{"t":810.000032991976,"s":[0,0,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908],[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908]],"o":[[2.234,0.849],[0.908,2.021],[-0.849,2.234],[-2.021,0.908],[-2.234,-0.849],[-0.908,-2.021],[0.849,-2.234],[2.021,-0.908]],"v":[[-1027.649,-909.981],[-1022.829,-905.437],[-1022.633,-898.815],[-1027.177,-893.995],[-1033.799,-893.8],[-1038.619,-898.344],[-1038.814,-904.966],[-1034.27,-909.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949,0.4784,0.251,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-230.000009368092,"op":1265.00005152451,"st":-230.000009368092,"ct":1,"bm":0}],"markers":[]} diff --git a/public/app/fn-app/fn-app-provider.tsx b/public/app/fn-app/fn-app-provider.tsx index 07cee337f5571..496a90a777821 100644 --- a/public/app/fn-app/fn-app-provider.tsx +++ b/public/app/fn-app/fn-app-provider.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, FC } from 'react'; +import React, { useState, useEffect, FC, PropsWithChildren } from 'react'; import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; @@ -6,6 +6,7 @@ import { config, navigationLogger } from '@grafana/runtime'; import { ErrorBoundaryAlert, GlobalStyles } from '@grafana/ui'; import { loadAndInitAngularIfEnabled } from 'app/angular/loadAndInitAngularIfEnabled'; import { ThemeProvider } from 'app/core/utils/ConfigProvider'; +import { FnLoader } from 'app/features/dashboard/components/DashboardLoading/FnLoader'; import { store } from 'app/store/store'; import { GrafanaContext } from '../core/context/GrafanaContext'; @@ -15,8 +16,8 @@ import { FNDashboardProps } from './types'; type FnAppProviderProps = Pick; -export const FnAppProvider: FC = (props) => { - const { children, fnError = null } = props; +export const FnAppProvider: FC> = (props) => { + const { children } = props; const [ready, setReady] = useState(false); navigationLogger('AppWrapper', false, 'rendering'); @@ -24,24 +25,13 @@ export const FnAppProvider: FC = (props) => { loadAndInitAngularIfEnabled() .then(() => { setReady(true); - // $('.preloader').remove(); }) .catch((err) => console.error(err)); return () => {}; }, []); - if (!ready) { - /** - * TODO: I think loader would be better - */ - return <>{fnError}; - } - - if (!store) { - /** - * TODO: I think loader would be better - */ - return <>{fnError}; + if (!store || !ready) { + return ; } return ( diff --git a/yarn.lock b/yarn.lock index 91dc05449cd50..39765319e9fba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22818,41 +22818,10 @@ __metadata: "merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 - resolution: "merge2@npm:1.4.1" checksum: 10/7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 languageName: node linkType: hard -"methods@npm:~1.1.2": - version: 1.1.2 - resolution: "methods@npm:1.1.2" - checksum: 10/a385dd974faa34b5dd021b2bbf78c722881bf6f003bfe6d391d7da3ea1ed625d1ff10ddd13c57531f628b3e785be38d3eed10ad03cebd90b76932413df9a1820 - languageName: node - linkType: hard - -"micro-memoize@npm:^4.1.2": - version: 4.1.2 - resolution: "micro-memoize@npm:4.1.2" - checksum: 10/027e90c3147c97c07224440ea50ede27eb7d888149e4925820397b466d16efc525f5ec3981e4cadec3258a8d36dfd5e7e7c8e660879fbe2e47106785be9bc570 - languageName: node - linkType: hard - -"micromark-core-commonmark@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-core-commonmark@npm:2.0.1" - dependencies: - decode-named-character-reference: "npm:^1.0.0" - devlop: "npm:^1.0.0" - micromark-factory-destination: "npm:^2.0.0" - micromark-factory-label: "npm:^2.0.0" - micromark-factory-space: "npm:^2.0.0" - micromark-factory-title: "npm:^2.0.0" - micromark-factory-whitespace: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-chunked: "npm:^2.0.0" - micromark-util-classify-character: "npm:^2.0.0" - micromark-util-html-tag-name: "npm:^2.0.0" - micromark-util-normalize-identifier: "npm:^2.0.0" micromark-util-resolve-all: "npm:^2.0.0" micromark-util-subtokenize: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" From 60eccc20962544386c50e5f05200b634d05638b6 Mon Sep 17 00:00:00 2001 From: Harjot Gill Date: Tue, 12 Dec 2023 10:59:37 -0800 Subject: [PATCH 075/101] remove reviewer --- .github/workflows/openai-review.yml | 31 ----------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/workflows/openai-review.yml diff --git a/.github/workflows/openai-review.yml b/.github/workflows/openai-review.yml deleted file mode 100644 index 26ed606af4e5e..0000000000000 --- a/.github/workflows/openai-review.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: OpenAI Reviewer - -permissions: - contents: read - pull-requests: write - -on: - pull_request: - pull_request_review_comment: - types: [created] - -concurrency: - group: - ${{ github.repository }}-${{ github.event.number || github.head_ref || - github.sha }}-${{ github.workflow }}-${{ github.event_name == - 'pull_request_review_comment' && 'pr_comment' || 'pr' }} - cancel-in-progress: ${{ github.event_name != 'pull_request_review_comment' }} - -jobs: - review: - runs-on: ubuntu-latest - steps: - - uses: fluxninja/openai-pr-reviewer@main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - with: - openai_heavy_model: gpt-4 - debug: false - review_comment_lgtm: false - max_files: 80 From f200422ace0959a0e3266b7ba389984d759e81e4 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Tue, 12 Dec 2023 14:29:19 -0500 Subject: [PATCH 076/101] loader color fix (#150) --- .../components/DashboardLoading/FnLoader.tsx | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx b/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx index 751ae08e747ca..e78b27c055e12 100644 --- a/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx +++ b/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx @@ -1,6 +1,8 @@ import { Box, CircularProgress, CircularProgressProps, Typography, type BoxProps } from '@mui/material'; import React, { type ReactNode, type FC, type HTMLAttributes } from 'react'; +import { useTheme2 } from '@grafana/ui'; + import logoUrl from './fn-logo.svg'; export type FnLoaderProps = { @@ -17,25 +19,32 @@ export const FnLoader: FC = ({ circularProgressProps, imageProps, text, -}) => ( - - {'FluxNinja - - +}) => { + const theme = useTheme2(); + + return ( + + {'FluxNinja + + + + {typeof text === 'string' ? {text} : text || null} - {typeof text === 'string' ? {text} : text || null} - -); + ); +}; From 8e00f776f3eadb8b72ae25d22feefc35bed254e2 Mon Sep 17 00:00:00 2001 From: Harjot Gill Date: Thu, 21 Dec 2023 11:43:29 -0800 Subject: [PATCH 077/101] page title Flux Ninja -> FluxNinja --- .../app/core/components/Page/usePageTitle.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/public/app/core/components/Page/usePageTitle.ts b/public/app/core/components/Page/usePageTitle.ts index 44e5e2d1d60bf..42e548cdcc206 100644 --- a/public/app/core/components/Page/usePageTitle.ts +++ b/public/app/core/components/Page/usePageTitle.ts @@ -1,13 +1,12 @@ -import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; +import {useEffect} from 'react'; -import { NavModel, NavModelItem } from '@grafana/data'; -import { HOME_NAV_ID } from 'app/core/reducers/navModel'; -import { FnGlobalState } from 'app/core/reducers/fn-slice'; -import type { StoreState } from 'app/types'; +import {NavModel, NavModelItem} from '@grafana/data'; +import {FnGlobalState} from 'app/core/reducers/fn-slice'; +import {HOME_NAV_ID} from 'app/core/reducers/navModel'; +import {StoreState, useSelector} from 'app/types'; -import { Branding } from '../Branding/Branding'; -import { buildBreadcrumbs } from '../Breadcrumbs/utils'; +import {Branding} from '../Branding/Branding'; +import {buildBreadcrumbs} from '../Breadcrumbs/utils'; export function usePageTitle(navModel?: NavModel, pageNav?: NavModelItem) { const homeNav = useSelector((state) => state.navIndex)[HOME_NAV_ID]; @@ -22,6 +21,6 @@ export function usePageTitle(navModel?: NavModel, pageNav?: NavModelItem) { // Override `Home` with the custom brand title parts[parts.length - 1] = Branding.AppTitle; - document.title = !FNDashboard ? parts.join(' - ') : pageTitle ? pageTitle : 'Flux Ninja'; - }, [homeNav, navModel, pageNav]); + document.title = !FNDashboard ? parts.join(' - ') : pageTitle ? pageTitle : 'FluxNinja'; + }, [FNDashboard, homeNav, navModel, pageNav, pageTitle]); } From 83184f2076179d5d90a9296f15d1d1a53d143fa5 Mon Sep 17 00:00:00 2001 From: Jaseel <12792882+Spikatrix@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:59:45 +0530 Subject: [PATCH 078/101] Add allowed cookies field in druid datasource settings (#171) --- .../ConfigEditor.tsx | 5 +++-- .../ConnectionSettings/DruidHttpSettings.tsx | 18 ++++++++++++++++-- .../configuration/ConnectionSettings/types.ts | 3 +++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/ConfigEditor.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/ConfigEditor.tsx index b1bb2016dd2f9..92b4e051d5da2 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/ConfigEditor.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/ConfigEditor.tsx @@ -55,9 +55,9 @@ export class ConfigEditor extends PureComponent { onConnectionOptionsChange = (connectionSettingsOptions: ConnectionSettingsOptions) => { const { options, onOptionsChange } = this.props; - const { settings, secretSettings, secretSettingsFields } = connectionSettingsOptions; + const { settings, secretSettings, secretSettingsFields, jsonData: connectionJsonData } = connectionSettingsOptions; const connectionSettings = this.normalizeData(settings, true, 'connection'); - const jsonData = { ...options.jsonData, ...connectionSettings }; + const jsonData = { ...options.jsonData, ...connectionSettings, ...connectionJsonData }; const connectionSecretSettings = this.normalizeData(secretSettings, true, 'connection'); const secureJsonData = { ...options.secureJsonData, ...connectionSecretSettings }; const connectionSecretSettingsFields = this.normalizeData( @@ -83,6 +83,7 @@ export class ConfigEditor extends PureComponent { settings: this.normalizeData(jsonData, false, 'connection'), secretSettings: this.normalizeData(secureJsonData || {}, false, 'connection'), secretSettingsFields: this.normalizeData(secureJsonFields || {}, false, 'connection') as KeyValue, + jsonData: { keepCookies: (jsonData as ConnectionSettingsOptions['jsonData'])?.keepCookies || [] }, }; }; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidHttpSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidHttpSettings.tsx index 7ffa41c589f07..de3673ff42f0e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidHttpSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidHttpSettings.tsx @@ -1,6 +1,7 @@ import React, { ChangeEvent } from 'react'; -import { LegacyForms, FieldSet, Field, Switch } from '@grafana/ui'; -import { css } from '@emotion/css'; + +import { LegacyForms, FieldSet, Field, Switch, TagsInput, InlineFormLabel } from '@grafana/ui'; + import { ConnectionSettingsProps } from './types'; const { FormField } = LegacyForms; @@ -90,6 +91,19 @@ export const DruidHttpSettings = (props: ConnectionSettingsProps) => { )} +
+ + Allowed cookies + + onOptionsChange({ ...options, jsonData: { keepCookies: cookies } })} + /> +
); }; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/types.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/types.ts index 8426f0a008074..2354e91a6de81 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/types.ts +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/types.ts @@ -16,6 +16,9 @@ export interface ConnectionSettingsOptions { settings: ConnectionSettings; secretSettings: ConnectionSecretSettings; secretSettingsFields: KeyValue; + jsonData?: { + keepCookies?: string[]; + }, } export interface ConnectionSettingsProps { From a2883dde76efb7dc2990b1cda22c17341087903a Mon Sep 17 00:00:00 2001 From: Jaseel <12792882+Spikatrix@users.noreply.github.com> Date: Tue, 9 Jan 2024 01:18:38 +0530 Subject: [PATCH 079/101] Fix sentry heatmap crash (#168) Co-authored-by: Gurinder Singh --- public/app/plugins/panel/heatmap/utils.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/public/app/plugins/panel/heatmap/utils.ts b/public/app/plugins/panel/heatmap/utils.ts index 3618dcdef2dc4..4b97f4acf8458 100644 --- a/public/app/plugins/panel/heatmap/utils.ts +++ b/public/app/plugins/panel/heatmap/utils.ts @@ -601,6 +601,15 @@ export function heatmapPathsDense(opts: PathbuilderOpts) { let cx = cxs[~~(i / yBinQty)]; let cy = cys[i % yBinQty]; + if ( + fills === undefined || + fills[i] === undefined || + fillPaths === undefined || + fillPaths[fills[i]] === undefined + ) { + continue; + } + let fillPath = fillPaths[fills[i]]; rect(fillPath, cx, cy, xSize, ySize); From 2ce8ced642feb8ed899d969dc3709e1da5a39221 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Mon, 8 Jan 2024 23:40:05 -0500 Subject: [PATCH 080/101] removed make doc workflow (#172) --- .github/workflows/update-make-docs.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/update-make-docs.yml diff --git a/.github/workflows/update-make-docs.yml b/.github/workflows/update-make-docs.yml deleted file mode 100644 index 49b64504bd0db..0000000000000 --- a/.github/workflows/update-make-docs.yml +++ /dev/null @@ -1,19 +0,0 @@ -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: - - uses: actions/checkout@v4 - - uses: grafana/writers-toolkit/update-make-docs@update-make-docs/v1 - with: - pr_options: > - --label 'backport v10.1.x' - --label 'backport v10.2.x' - --label 'backport v10.3.x' - --label no-changelog - --label type/docs From 0306b491e951fe6d9a57aa2135299ade674d59c6 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Mon, 15 Jul 2024 09:21:18 -0400 Subject: [PATCH 081/101] Coderabbit theme and fixes (#175) * coderabbit theme * theme change * checkpoint * fixes * added coderabbit authentication --- .betterer.results | 6 +- .yarn/sdks/eslint/lib/unsupported-api.js | 27 ++ .yarn/sdks/prettier/bin/prettier.cjs | 27 ++ .../grafana-data/src/themes/breakpoints.ts | 2 +- .../grafana-data/src/themes/createColors.ts | 20 +- .../src/themes/createTypography.ts | 12 +- .../grafana-data/src/themes/fnCreateColors.ts | 240 ------------------ packages/grafana-data/src/themes/fnPalette.ts | 42 --- .../CustomScrollbar/CustomScrollbar.tsx | 6 +- .../DateTimePickers/TimeRangePicker.tsx | 13 +- .../TimeRangePicker/TimePickerFooter.tsx | 2 +- .../src/components/Portal/Portal.tsx | 7 +- .../src/themes/GlobalStyles/forms.ts | 2 - .../src/themes/_variables.scss.tmpl.ts | 8 +- packages/grafana-ui/src/themes/default.ts | 4 +- public/app/core/services/backend_srv.ts | 24 ++ .../DashboardLoading/CodeRabbitLogo.tsx | 20 ++ .../components/DashboardLoading/FnLoader.tsx | 8 +- .../components/DashboardLoading/fn-logo.svg | 9 - public/app/fn_dashboard.ts | 15 +- public/microfrontends/fn_dashboard/index.html | 28 +- public/sass/_variables.generated.scss | 32 +-- public/sass/_variables.light.generated.scss | 88 +++---- .../views/index-microfrontend-template.html | 20 +- 24 files changed, 228 insertions(+), 434 deletions(-) create mode 100644 .yarn/sdks/eslint/lib/unsupported-api.js create mode 100755 .yarn/sdks/prettier/bin/prettier.cjs delete mode 100644 packages/grafana-data/src/themes/fnCreateColors.ts delete mode 100644 packages/grafana-data/src/themes/fnPalette.ts create mode 100644 public/app/features/dashboard/components/DashboardLoading/CodeRabbitLogo.tsx delete mode 100644 public/app/features/dashboard/components/DashboardLoading/fn-logo.svg diff --git a/.betterer.results b/.betterer.results index 06ec3c24f15a9..62ebfad127c80 100644 --- a/.betterer.results +++ b/.betterer.results @@ -1296,11 +1296,7 @@ exports[`better eslint`] = { ], "public/app/core/services/backend_srv.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.", "5"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "public/app/core/services/context_srv.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], diff --git a/.yarn/sdks/eslint/lib/unsupported-api.js b/.yarn/sdks/eslint/lib/unsupported-api.js new file mode 100644 index 0000000000000..f5f8e24d0e3cc --- /dev/null +++ b/.yarn/sdks/eslint/lib/unsupported-api.js @@ -0,0 +1,27 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require eslint/use-at-your-own-risk + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +// Defer to the real eslint/use-at-your-own-risk your application uses +module.exports = absRequire(`eslint/use-at-your-own-risk`); diff --git a/.yarn/sdks/prettier/bin/prettier.cjs b/.yarn/sdks/prettier/bin/prettier.cjs new file mode 100755 index 0000000000000..00f1f7f745b47 --- /dev/null +++ b/.yarn/sdks/prettier/bin/prettier.cjs @@ -0,0 +1,27 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require prettier/bin/prettier.cjs + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +// Defer to the real prettier/bin/prettier.cjs your application uses +module.exports = absRequire(`prettier/bin/prettier.cjs`); diff --git a/packages/grafana-data/src/themes/breakpoints.ts b/packages/grafana-data/src/themes/breakpoints.ts index 1ad0d7137810e..9edee52f8e12a 100644 --- a/packages/grafana-data/src/themes/breakpoints.ts +++ b/packages/grafana-data/src/themes/breakpoints.ts @@ -28,7 +28,7 @@ export function createBreakpoints(): ThemeBreakpoints { const values: ThemeBreakpointValues = { xs: 0, sm: 544, - md: 769, // 1 more than regular ipad in portrait + md: 768, // 1 more than regular ipad in portrait lg: 992, xl: 1200, xxl: 1440, diff --git a/packages/grafana-data/src/themes/createColors.ts b/packages/grafana-data/src/themes/createColors.ts index fb89dd2f2a629..2b02ddfb21611 100644 --- a/packages/grafana-data/src/themes/createColors.ts +++ b/packages/grafana-data/src/themes/createColors.ts @@ -171,16 +171,16 @@ class LightColors implements ThemeColorsBase> { blackBase = '45, 51, 62'; primary = { - main: '#8EC4AD', - border: palette.blueLightText, - text: '#F0E4B6', + main: '#FF4702', + border: '#E33E00', + text: '#101828', }; text = { - primary: '#2D333E', - secondary: '#2d333e', + primary: '#101828', + secondary: '#344054', disabled: '#9DA7B8', - link: this.primary.text, + link: '#FF4702', maxContrast: palette.black, }; @@ -191,7 +191,7 @@ class LightColors implements ThemeColorsBase> { }; secondary = { - main: '#FC9A69', + main: '#FF4702', shade: '#FC9A6990', contrastText: `rgba(${this.blackBase}, 1)`, text: this.text.primary, @@ -220,9 +220,9 @@ class LightColors implements ThemeColorsBase> { }; background = { - canvas: '#F6F5F3', - primary: '#FDFDFC', - secondary: '#FDFDFC', + primary: '#FAFAFA', + canvas: '#FFFFFF', + secondary: '#FAFAFA', }; action = { diff --git a/packages/grafana-data/src/themes/createTypography.ts b/packages/grafana-data/src/themes/createTypography.ts index 275522982983a..d0c8fe8189476 100644 --- a/packages/grafana-data/src/themes/createTypography.ts +++ b/packages/grafana-data/src/themes/createTypography.ts @@ -53,8 +53,8 @@ export interface ThemeTypographyInput { htmlFontSize?: number; } -const defaultFontFamily = '"Source Sans Pro", Nunito, Roboto, Arial'; //'"Roboto", "Helvetica", "Arial", sans-serif'; -const defaultFontFamilyMonospace = "'Nunito Mono', 'Roboto Mono', monospace"; // "'Roboto Mono', monospace"; +const defaultFontFamily = '"Poppins", Inter, Satoshi, sans-serif'; //'"Roboto", "Helvetica", "Arial", sans-serif'; +const defaultFontFamilyMonospace = '"SatoshiLight", "FigtreeLight", monospace'; // "'Roboto Mono', monospace"; export function createTypography(colors: ThemeColors, typographyInput: ThemeTypographyInput = {}): ThemeTypography { const { @@ -62,13 +62,13 @@ export function createTypography(colors: ThemeColors, typographyInput: ThemeTypo fontFamilyMonospace = defaultFontFamilyMonospace, // The default font size of the Material Specification. fontSize = 14, // px - fontWeightLight = 300, - fontWeightRegular = 400, - fontWeightMedium = 500, + fontWeightLight = 200, + fontWeightRegular = 300, + fontWeightMedium = 400, fontWeightBold = 500, // Tell Grafana-UI what's the font-size on the html element. // 16px is the default font-size used by browsers. - htmlFontSize = 14, + htmlFontSize = 16, } = typographyInput; if (process.env.NODE_ENV !== 'production') { diff --git a/packages/grafana-data/src/themes/fnCreateColors.ts b/packages/grafana-data/src/themes/fnCreateColors.ts deleted file mode 100644 index f7705578cdf61..0000000000000 --- a/packages/grafana-data/src/themes/fnCreateColors.ts +++ /dev/null @@ -1,240 +0,0 @@ -import { merge } from 'lodash'; - -import { alpha, darken, emphasize, getContrastRatio, lighten } from './colorManipulator'; -import { ThemeColorsBase, ThemeColorsMode, ThemeColors, ThemeColorsInput } from './createColors'; -import { palette } from './fnPalette'; -import { ThemeRichColor } from './types'; - -interface GetRichColorProps { - color: Partial; - name: string; -} - -class FnDarkColors implements ThemeColorsBase> { - mode: ThemeColorsMode = 'dark'; - - // Used to get more white opacity colors - whiteBase = '219, 217, 215'; - - border = { - weak: `rgba(${this.whiteBase}, 0.07)`, - medium: `rgba(${this.whiteBase}, 0.15)`, - strong: `rgba(${this.whiteBase}, 0.25)`, - }; - - text = { - primary: '#DBD9D7', - secondary: '#F0E4B6', // yellow - disabled: '#9DA7B8', - link: '#F0E4B6', // yellow - maxContrast: '#F0E4B6', // yellow - }; - - primary = { - main: '#3F8367', - text: '#F0E4B6', // yellow - border: '#ffffff00', - }; - - secondary = { - main: '#F06929', - shade: '#F0692955', - text: this.text.primary, - contrastText: `rgb(${this.whiteBase})`, - border: this.border.strong, - }; - - info = this.primary; - - error = { - main: palette.redDarkMain, - text: palette.redDarkText, - }; - - success = { - main: '#4BBF73', - text: '#318B50', - }; - - warning = { - main: '#CF8E07', - text: this.text.primary, - }; - - background = { - canvas: '#312D2B', //palette.gray05, - primary: '#3B3835', //palette.gray10, - secondary: '#5E5855', //palette.gray15, - }; - - action = { - hover: `rgba(${this.whiteBase}, 0.16)`, - selected: `rgba(${this.whiteBase}, 0.12)`, - focus: `rgba(${this.whiteBase}, 0.16)`, - hoverOpacity: 0.08, - disabledText: this.text.disabled, - disabledBackground: `rgba(${this.whiteBase}, 0.04)`, - disabledOpacity: 0.38, - selectedBorder: palette.orangeDarkMain, - }; - - gradients = { - brandHorizontal: 'linear-gradient(270deg, #F55F3E 0%, #FF8833 100%)', - brandVertical: 'linear-gradient(0.01deg, #F55F3E 0.01%, #FF8833 99.99%)', - }; - - contrastThreshold = 3; - hoverFactor = 0.03; - tonalOffset = 0.15; -} - -class FnLightColors implements ThemeColorsBase> { - mode: ThemeColorsMode = 'light'; - - blackBase = '45, 51, 62'; - - primary = { - main: '#8EC4AD', - border: palette.blueLightText, - text: '#2d333e', // yellow - }; - - text = { - primary: '#2D333E', - secondary: '#2d333e', - disabled: '#9DA7B8', - link: this.primary.text, - maxContrast: palette.black, - }; - - border = { - weak: `rgba(${this.blackBase}, 0.12)`, - medium: `rgba(${this.blackBase}, 0.30)`, - strong: `rgba(${this.blackBase}, 0.40)`, - }; - - secondary = { - main: '#FC9A69', - shade: '#FC9A6990', - contrastText: `rgba(${this.blackBase}, 1)`, - text: this.text.primary, - border: this.border.strong, - }; - - info = { - main: '#64B6F7', - text: palette.blueLightText, - }; - - error = { - main: palette.redLightMain, - text: palette.redLightText, - border: palette.redLightText, - }; - - success = { - main: '#83D39E', - text: palette.greenLightText, - }; - - warning = { - main: '#EB7B18', // FN color - text: palette.orangeLightText, - }; - - background = { - canvas: '#F6F5F3', - primary: '#FDFDFC', - secondary: '#FDFDFC', - }; - - action = { - hover: `rgba(${this.blackBase}, 0.12)`, - selected: `#F27A40`, - hoverOpacity: 0.08, - focus: `rgba(${this.blackBase}, 0.12)`, - disabledBackground: `rgba(${this.blackBase}, 0.04)`, - disabledText: this.text.disabled, - disabledOpacity: 0.38, - selectedBorder: palette.orangeLightMain, - }; - - gradients = { - brandHorizontal: 'linear-gradient(90deg, #FF8833 0%, #F53E4C 100%)', - brandVertical: 'linear-gradient(0.01deg, #F53E4C -31.2%, #FF8833 113.07%)', - }; - - contrastThreshold = 3; - hoverFactor = 0.03; - tonalOffset = 0.2; -} - -// NOTE: createFnColors used in create-mfe to create grafana theme2 colors -export function createFnColors(colors: ThemeColorsInput): ThemeColors { - const dark = new FnDarkColors(); - const light = new FnLightColors(); - - const base = (colors.mode ?? 'dark') === 'dark' ? dark : light; - - const { - primary = base.primary, - secondary = base.secondary, - info = base.info, - warning = base.warning, - success = base.success, - error = base.error, - tonalOffset = base.tonalOffset, - hoverFactor = base.hoverFactor, - contrastThreshold = base.contrastThreshold, - ...other - } = colors; - - function getContrastText(background: string, threshold: number = contrastThreshold) { - const contrastText = - getContrastRatio(dark.text.maxContrast, background, base.background.primary) >= threshold - ? dark.text.maxContrast - : light.text.maxContrast; - // todo, need color framework - return contrastText; - } - - const getRichColor = ({ color, name }: GetRichColorProps): ThemeRichColor => { - color = { ...color, name }; - if (!color.main) { - throw new Error(`Missing main color for ${name}`); - } - if (!color.text) { - color.text = color.main; - } - if (!color.border) { - color.border = color.text; - } - if (!color.shade) { - color.shade = base.mode === 'light' ? darken(color.main, tonalOffset) : lighten(color.main, tonalOffset); - } - if (!color.transparent) { - color.transparent = base.mode === 'light' ? alpha(color.main, 0.08) : alpha(color.main, 0.15); - } - if (!color.contrastText) { - color.contrastText = getContrastText(color.main); - } - return color as ThemeRichColor; - }; - - return merge( - { - ...base, - primary: getRichColor({ color: primary, name: 'primary' }), - secondary: getRichColor({ color: secondary, name: 'secondary' }), - info: getRichColor({ color: info, name: 'info' }), - error: getRichColor({ color: error, name: 'error' }), - success: getRichColor({ color: success, name: 'success' }), - warning: getRichColor({ color: warning, name: 'warning' }), - getContrastText, - emphasize: (color: string, factor?: number) => { - return emphasize(color, factor ?? hoverFactor); - }, - }, - other - ); -} diff --git a/packages/grafana-data/src/themes/fnPalette.ts b/packages/grafana-data/src/themes/fnPalette.ts deleted file mode 100644 index 48fcd7751fa9f..0000000000000 --- a/packages/grafana-data/src/themes/fnPalette.ts +++ /dev/null @@ -1,42 +0,0 @@ -export const palette = { - white: '#FFFFFF', - black: '#000000', - - gray25: '#2c3235', - gray15: '#22252b', - gray10: '#181b1f', - gray05: '#111217', - - darkLayer0: '#18181A', - darkLayer1: '#212124', - darkLayer2: '#2a2a2f', - - darkBorder1: '#34343B', - darkBorder2: '#64646B', - - // Dashboard bg / layer 0 (light theme) - gray90: '#F4F5F5', - // Card bg / layer 1 - gray100: '#F4F5F5', - // divider line - gray80: '#D0D1D3', - lightBorder1: '#E4E7E7', - - blueDarkMain: '#3D71D9', - blueDarkText: '#6E9FFF', - redDarkMain: '#D9534F', // FN - same as in light, final color to be agreed - redDarkText: '#13161B', // FN - same as in light, final color to be agreed - greenDarkMain: '#1A7F4B', - greenDarkText: '#6CCF8E', - orangeDarkMain: '#F5B73D', - orangeDarkText: '#F8D06B', - - blueLightMain: '#3871DC', - blueLightText: '#1F62E0', - redLightMain: '#D9534F', // FN - redLightText: '#13161B', // FN - greenLightMain: '#1B855E', - greenLightText: '#0A764E', - orangeLightMain: '#FAD34A', - orangeLightText: '#8A6C00', -}; diff --git a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx index ac775afbe97b3..4e66cd7086f2d 100644 --- a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx +++ b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx @@ -116,10 +116,8 @@ export const CustomScrollbar = ({ passedProps.style['WebkitOverflowScrolling'] = 'auto'; } - return
; - }, - [divId] - ); + return
; + }, []); const onScrollStop = useCallback(() => { ref.current && setScrollTop && setScrollTop(ref.current.getValues()); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx index 2350bd10c50c4..fa389edb7792f 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx @@ -137,9 +137,8 @@ export function TimeRangePicker(props: TimeRangePickerProps) { )} } - placement="bottom" + placement="bottom-start" interactive > )} - + ( - <> - - Time range zoom out
CTRL+Z -
- + + Time range zoom out
CTRL+Z +
); export const TimePickerTooltip = ({ timeRange, timeZone }: { timeRange: TimeRange; timeZone?: TimeZone }) => { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx index c596ddc9a9acf..c8ef511d31163 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx @@ -63,7 +63,7 @@ export const TimePickerFooter = (props: Props) => { return null; } - const fnColor = theme.isDark ? '#8EC4AD' : '#3A785E'; + const fnColor = theme.isDark ? '#8EC4AD' : '#344054'; return (
diff --git a/packages/grafana-ui/src/components/Portal/Portal.tsx b/packages/grafana-ui/src/components/Portal/Portal.tsx index 1dd8e29b374e8..93d5f8d7fa889 100644 --- a/packages/grafana-ui/src/components/Portal/Portal.tsx +++ b/packages/grafana-ui/src/components/Portal/Portal.tsx @@ -40,7 +40,12 @@ export function Portal(props: PropsWithChildren) { }; }, [portalRoot]); - return ReactDOM.createPortal(
{children}
, node.current); + return ReactDOM.createPortal( +
+ {children} +
, + node.current + ); } /** @internal */ diff --git a/packages/grafana-ui/src/themes/GlobalStyles/forms.ts b/packages/grafana-ui/src/themes/GlobalStyles/forms.ts index 2cc1b03e94a23..317d92b3a075e 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/forms.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/forms.ts @@ -10,14 +10,12 @@ export function getFormElementStyles(theme: GrafanaTheme2) { fontWeight: theme.typography.body.fontWeight, lineHeight: theme.typography.body.lineHeight, }, - 'input, select': { backgroundColor: theme.components.input.background, color: theme.components.input.text, border: 'none', boxShadow: 'none', }, - textarea: { height: 'auto', }, diff --git a/packages/grafana-ui/src/themes/_variables.scss.tmpl.ts b/packages/grafana-ui/src/themes/_variables.scss.tmpl.ts index 75a8ad0d4af3d..3f6b60eed7fa5 100644 --- a/packages/grafana-ui/src/themes/_variables.scss.tmpl.ts +++ b/packages/grafana-ui/src/themes/_variables.scss.tmpl.ts @@ -75,10 +75,10 @@ $grid-breakpoints: ( // Define the maximum width of \`.container\` for different screen sizes. $container-max-widths: ( - sm: 576px, - md: 720px, - lg: 940px, - xl: 1080px, + sm: 640px, + md: 768px, + lg: 1024px, + xl: 1536px, ) !default; // Grid columns diff --git a/packages/grafana-ui/src/themes/default.ts b/packages/grafana-ui/src/themes/default.ts index f5490b72c0bc7..78fb03350cacf 100644 --- a/packages/grafana-ui/src/themes/default.ts +++ b/packages/grafana-ui/src/themes/default.ts @@ -31,8 +31,8 @@ const theme: GrafanaThemeCommons = { name: 'Grafana Default', typography: { fontFamily: { - sansSerif: '"Inter", "Helvetica", "Arial", sans-serif', - monospace: "'Roboto Mono', monospace", + sansSerif: '"Poppins", Inter, Satoshi, sans-serif', + monospace: '"SatoshiLight", "FigtreeLight", monospace', }, size: { base: '14px', diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 83cbcb416b3b5..372170b6a72e2 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -189,6 +189,18 @@ export class BackendSrv implements BackendService { return lastValueFrom(this.fetch(options)); } + private getCodeRabbitOrg(): { id: string } | null { + const selectedOrgStorage = sessionStorage.getItem('selected_org'); + + try { + return selectedOrgStorage ? (JSON.parse(selectedOrgStorage) as { id: string }) : null; + } catch (e) { + console.error('Failed to parse selected_org', selectedOrgStorage, 'error:', e); + sessionStorage.removeItem('selected_org'); + return null; + } + } + private parseRequestOptions(options: BackendSrvRequest): BackendSrvRequest { const orgId = this.dependencies.contextSrv.user?.orgId; @@ -201,10 +213,22 @@ export class BackendSrv implements BackendService { options.headers['X-Grafana-Org-Id'] = orgId; } + const codeRabbitOrg = this.getCodeRabbitOrg(); + if (codeRabbitOrg) { + options.headers = options.headers ?? {}; + options.headers['x-coderabbit-organization'] = codeRabbitOrg.id; + } + if (options.url.startsWith('/')) { options.url = options.url.substring(1); } + const codeRabbitToken = sessionStorage.getItem('accessToken'); + if (codeRabbitToken) { + options.headers = options.headers ?? {}; + options.headers['x-coderabbit-token'] = `Bearer ${codeRabbitToken}`; + } + if (options.headers?.Authorization) { options.headers['X-DS-Authorization'] = options.headers.Authorization; delete options.headers.Authorization; diff --git a/public/app/features/dashboard/components/DashboardLoading/CodeRabbitLogo.tsx b/public/app/features/dashboard/components/DashboardLoading/CodeRabbitLogo.tsx new file mode 100644 index 0000000000000..2cadfda7b1f23 --- /dev/null +++ b/public/app/features/dashboard/components/DashboardLoading/CodeRabbitLogo.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +type LogoFullProps = React.SVGProps; + +export const CodeRabbitLogo: React.FC = (props) => { + return ( + + + + + ); +}; diff --git a/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx b/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx index e78b27c055e12..142aaa4b95dd4 100644 --- a/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx +++ b/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx @@ -1,15 +1,14 @@ import { Box, CircularProgress, CircularProgressProps, Typography, type BoxProps } from '@mui/material'; -import React, { type ReactNode, type FC, type HTMLAttributes } from 'react'; +import React, { type ReactNode, type FC } from 'react'; import { useTheme2 } from '@grafana/ui'; -import logoUrl from './fn-logo.svg'; +import { CodeRabbitLogo } from './CodeRabbitLogo'; export type FnLoaderProps = { outerContainerProps?: Omit; innerContainerProps?: Omit; circularProgressProps?: CircularProgressProps; - imageProps?: HTMLAttributes; text?: ReactNode; }; @@ -17,7 +16,6 @@ export const FnLoader: FC = ({ outerContainerProps, innerContainerProps, circularProgressProps, - imageProps, text, }) => { const theme = useTheme2(); @@ -31,7 +29,7 @@ export const FnLoader: FC = ({ paddingTop="150px" {...outerContainerProps} > - {'FluxNinja + - - - - - - - - \ No newline at end of file diff --git a/public/app/fn_dashboard.ts b/public/app/fn_dashboard.ts index 3110e1b907f72..04a8957f10e18 100644 --- a/public/app/fn_dashboard.ts +++ b/public/app/fn_dashboard.ts @@ -6,10 +6,21 @@ config.featureToggles = { ...config.featureToggles, publicDashboards: true, }; +interface FnData { + themePaths: { + light: string; + dark: string; + }; +} + +declare global { + interface Window { + fnData: FnData; + } +} config.isPublicDashboardView = false; -// eslint-disable-next-line -config.bootData.themePaths = (window as any).fnData?.themePaths; +config.bootData.themePaths = window.fnData.themePaths; export const { bootstrap, mount, unmount, update, afterMount, afterUnmount, beforeLoad, beforeMount, beforeUnmount } = createMfe.create(FNDashboard); diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index 6b4bb8a0c5584..fb0b659e1905e 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -1,35 +1,25 @@ - + - - FluxNinja Microfrontend + + CodeRabbit Micro-frontend - - +
- - + - + diff --git a/public/sass/_variables.generated.scss b/public/sass/_variables.generated.scss index db1ac2a5e3649..5edafebf856f9 100644 --- a/public/sass/_variables.generated.scss +++ b/public/sass/_variables.generated.scss @@ -67,7 +67,7 @@ $spacers: ( $grid-breakpoints: ( xs: 0px, sm: 544px, - md: 769px, + md: 768px, lg: 992px, xl: 1200px, ) !default; @@ -77,10 +77,10 @@ $grid-breakpoints: ( // Define the maximum width of `.container` for different screen sizes. $container-max-widths: ( - sm: 576px, - md: 720px, - lg: 940px, - xl: 1080px, + sm: 640px, + md: 768px, + lg: 1024px, + xl: 1536px, ) !default; // Grid columns @@ -99,9 +99,9 @@ $height-lg: 48; // Typography // ------------------------- /* stylelint-disable-next-line string-quotes */ -$font-family-sans-serif: "Source Sans Pro", Nunito, Roboto, Arial; +$font-family-sans-serif: "Poppins", Inter, Satoshi, sans-serif; /* stylelint-disable-next-line string-quotes */ -$font-family-monospace: 'Nunito Mono', 'Roboto Mono', monospace; +$font-family-monospace: "SatoshiLight", "FigtreeLight", monospace; $font-file-path: '../fonts' !default; @@ -114,15 +114,15 @@ $font-size-xs: 10px !default; $line-height-base: 1.5714285714285714 !default; -$font-weight-regular: 400 !default; -$font-weight-semi-bold: 500 !default; +$font-weight-regular: 300 !default; +$font-weight-semi-bold: 400 !default; -$font-size-h1: 2rem !default; -$font-size-h2: 1.7142857142857142rem !default; -$font-size-h3: 1.5714285714285714rem !default; -$font-size-h4: 1.2857142857142858rem !default; -$font-size-h5: 1.1428571428571428rem !default; -$font-size-h6: 1rem !default; +$font-size-h1: 1.75rem !default; +$font-size-h2: 1.5rem !default; +$font-size-h3: 1.375rem !default; +$font-size-h4: 1.125rem !default; +$font-size-h5: 1rem !default; +$font-size-h6: 0.875rem !default; $headings-line-height: 1.5 !default; @@ -177,7 +177,7 @@ $zindex-typeahead: 1030; $btn-padding-x: 14px !default; $btn-padding-y: 0 !default; $btn-line-height: $line-height-base; -$btn-font-weight: 500 !default; +$btn-font-weight: 400 !default; $btn-padding-x-sm: 7px !default; $btn-padding-y-sm: 4px !default; diff --git a/public/sass/_variables.light.generated.scss b/public/sass/_variables.light.generated.scss index 552a95785eb54..ca5a3930e6516 100644 --- a/public/sass/_variables.light.generated.scss +++ b/public/sass/_variables.light.generated.scss @@ -19,9 +19,9 @@ $colors-action-selected: #F27A40; // New Colors // ------------------------- -$blue-light: #F0E4B6; -$blue-base: #8EC4AD; -$blue-shade: rgb(113, 156, 138); +$blue-light: #101828; +$blue-base: #FF4702; +$blue-shade: rgb(204, 56, 1); $red-base: #E0226E; $red-shade: rgb(179, 27, 88); $green-base: #83D39E; @@ -57,9 +57,9 @@ $gray-7: #fbfbfb; $white: #ffffff; -$layer0: #F6F5F3; -$layer1: #FDFDFC; -$layer2: #FDFDFC; +$layer0: #FFFFFF; +$layer1: #FAFAFA; +$layer2: #FAFAFA; $divider: rgba(45, 51, 62, 0.12); $border0: rgba(45, 51, 62, 0.12); @@ -67,12 +67,12 @@ $border1: rgba(45, 51, 62, 0.30); // Accent colors // ------------------------- -$blue: #F0E4B6; +$blue: #101828; $red: $red-base; $yellow: #ecbb13; $orange: #eb7b18; $purple: #9933cc; -$variable: #F0E4B6; +$variable: #101828; $brand-primary: #eb7b18; $brand-success: #83D39E; @@ -93,17 +93,17 @@ $critical: #CF0E5B; // Scaffolding // ------------------------- -$body-bg: #F6F5F3; -$page-bg: #F6F5F3; -$dashboard-bg: #F6F5F3; +$body-bg: #FFFFFF; +$page-bg: #FFFFFF; +$dashboard-bg: #FFFFFF; -$text-color: #2D333E; +$text-color: #101828; $text-color-strong: #000000; -$text-color-semi-weak: #2d333e; -$text-color-weak: #2d333e; +$text-color-semi-weak: #344054; +$text-color-weak: #344054; $text-color-faint: #9DA7B8; $text-color-emphasis: #000000; -$text-blue: #F0E4B6; +$text-blue: #101828; $text-shadow-faint: none; @@ -113,14 +113,14 @@ $brand-gradient-vertical: linear-gradient(0.01deg, #F53E4C -31.2%, #FF8833 113.0 // Links // ------------------------- -$link-color: #2D333E; +$link-color: #101828; $link-color-disabled: #9DA7B8; $link-hover-color: #000000; -$external-link-color: #F0E4B6; +$external-link-color: #FF4702; // Typography // ------------------------- -$headings-color: #2D333E; +$headings-color: #101828; $abbr-border-color: $gray-2 !default; $text-muted: $text-color-weak; @@ -128,30 +128,30 @@ $hr-border-color: $gray-4 !default; // Panel // ------------------------- -$panel-bg: #FDFDFC; +$panel-bg: #FAFAFA; $panel-border: 1px solid rgba(45, 51, 62, 0.12); $panel-header-hover-bg: rgba(45, 51, 62, 0.12); $panel-box-shadow: none; $panel-corner: $panel-bg; // Page header -$page-header-bg: #F6F5F3; +$page-header-bg: #FFFFFF; $page-header-shadow: inset 0px -3px 10px $gray-6; -$page-header-border-color: #F6F5F3; +$page-header-border-color: #FFFFFF; $divider-border-color: $gray-2; // Graphite Target Editor -$tight-form-func-bg: #FDFDFC; -$tight-form-func-highlight-bg: #f9f9f6; +$tight-form-func-bg: #FAFAFA; +$tight-form-func-highlight-bg: #f5f5f5; -$modal-backdrop-bg: #FDFDFC; +$modal-backdrop-bg: #FAFAFA; $code-tag-bg: $gray-6; $code-tag-border: $gray-4; // cards -$card-background: #FDFDFC; -$card-background-hover: #FDFDFC; +$card-background: #FAFAFA; +$card-background-hover: #FAFAFA; $card-shadow: none; // Lists @@ -168,10 +168,10 @@ $scrollbarBorder: $gray-7; // Tables // ------------------------- -$table-bg-accent: #FDFDFC; +$table-bg-accent: #FAFAFA; $table-border: rgba(45, 51, 62, 0.30); -$table-bg-odd: rgb(247, 247, 246); -$table-bg-hover: rgb(240, 240, 239); +$table-bg-odd: rgb(245, 245, 245); +$table-bg-hover: rgb(237, 237, 237); // Buttons // ------------------------- @@ -207,16 +207,16 @@ $btn-active-box-shadow: 0px 0px 4px rgba(234, 161, 51, 0.6); // Forms // ------------------------- -$input-bg: #FDFDFC; +$input-bg: #FAFAFA; $input-bg-disabled: rgba(45, 51, 62, 0.04); -$input-color: #2D333E; +$input-color: #101828; $input-border-color: rgba(45, 51, 62, 0.30); $input-box-shadow: none; $input-border-focus: #5794f2; $input-box-shadow-focus: #5794f2; $input-color-placeholder: #9DA7B8; -$input-label-bg: #FDFDFC; +$input-label-bg: #FAFAFA; $input-color-select-arrow: #7b8087; // search @@ -229,7 +229,7 @@ $typeahead-selected-color: $yellow; // Dropdowns // ------------------------- -$dropdownBackground: #FDFDFC; +$dropdownBackground: #FAFAFA; $dropdownBorder: rgba(45, 51, 62, 0.12); $dropdownDividerTop: rgba(45, 51, 62, 0.12); $dropdownDividerBottom: rgba(45, 51, 62, 0.12); @@ -263,7 +263,7 @@ $side-menu-header-color: #e9edf2; // Menu dropdowns // ------------------------- -$menu-dropdown-bg: #FDFDFC; +$menu-dropdown-bg: #FAFAFA; $menu-dropdown-hover-bg: rgba(45, 51, 62, 0.12); $menu-dropdown-shadow: 0px 13px 20px 1px rgba(24, 26, 27, 0.18); @@ -283,16 +283,16 @@ $alert-warning-bg: #F3D086; $alert-info-bg: #F3D086; // Tooltips and popovers -$tooltipBackground: #FDFDFC; -$tooltipColor: #2D333E; -$tooltipArrowColor: #FDFDFC; +$tooltipBackground: #FAFAFA; +$tooltipColor: #101828; +$tooltipArrowColor: #FAFAFA; $tooltipBackgroundError: #E0226E; $tooltipShadow: 0px 4px 8px rgba(24, 26, 27, 0.2); -$popover-bg: #FDFDFC; -$popover-color: #2D333E; +$popover-bg: #FAFAFA; +$popover-color: #101828; $popover-border-color: rgba(45, 51, 62, 0.12); -$popover-header-bg: #FDFDFC; +$popover-header-bg: #FAFAFA; $popover-shadow: 0px 13px 20px 1px rgba(24, 26, 27, 0.18); $graph-tooltip-bg: $gray-5; @@ -305,7 +305,7 @@ $popover-error-bg: $btn-danger-bg; $popover-help-bg: $tooltipBackground; $popover-help-color: $tooltipColor; -$popover-code-bg: #FDFDFC; +$popover-code-bg: #FAFAFA; $popover-code-boxshadow: 0 0 5px $gray60; // images @@ -338,10 +338,10 @@ $diff-label-bg: rgba(45, 51, 62, 0.12); $diff-label-fg: $gray-2; $diff-arrow-color: $dark-2; -$diff-group-bg: #FDFDFC; +$diff-group-bg: #FAFAFA; -$diff-json-bg: #FDFDFC; -$diff-json-fg: #2D333E; +$diff-json-bg: #FAFAFA; +$diff-json-fg: #101828; $diff-json-added: $blue-shade; $diff-json-deleted: $red-shade; diff --git a/public/views/index-microfrontend-template.html b/public/views/index-microfrontend-template.html index a6205f112bad9..716020df9af66 100644 --- a/public/views/index-microfrontend-template.html +++ b/public/views/index-microfrontend-template.html @@ -1,20 +1,18 @@ - + - - FluxNinja Microfrontend + + CodeRabbit Micro-frontend - - +
- @@ -27,11 +25,7 @@ crossorigin="<%= webpackConfig.output.crossOriginLoading %>" > <% } else { %> - + <% } %> <% } %> From f869cab966ee919f4a0bbb1251f5622725806d36 Mon Sep 17 00:00:00 2001 From: dikshant-infracloud <160205839+dikshant-infracloud@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:44:03 +0530 Subject: [PATCH 082/101] Create deploy-cloud-run-grafana.yaml (#176) --- .../workflows/deploy-cloud-run-grafana.yaml | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/deploy-cloud-run-grafana.yaml diff --git a/.github/workflows/deploy-cloud-run-grafana.yaml b/.github/workflows/deploy-cloud-run-grafana.yaml new file mode 100644 index 0000000000000..504c38258d582 --- /dev/null +++ b/.github/workflows/deploy-cloud-run-grafana.yaml @@ -0,0 +1,48 @@ +name: Deploy Grafana Server Cloud Run + +on: + push: + branches: + - fluxninja_micro_frontends + paths: + - "/**" + workflow_dispatch: + +jobs: + build_and_deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ secrets.GOOGLECLOUDSA }} + + - uses: docker/setup-buildx-action@v3 + + - name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-${{ github.workflow }}-${{ github.sha }} + restore-keys: ${{ runner.os }}-${{ github.workflow }}- + + - run: gcloud auth configure-docker + + - uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: gcr.io/coderabbit/grafana:latest + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + build-contexts: | + mono=${{ github.workspace }} + + - name: Move Docker cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache + + # - name: Deploy to Cloud Run + # run: gcloud run deploy db-api-server --image gcr.io/coderabbit/db-api-server --region us-central1 --allow-unauthenticated --vpc-connector=coderabbitai-dev-cr From b34f7923c5329254fc0210d63705533582c3c2d9 Mon Sep 17 00:00:00 2001 From: dikshant-infracloud <160205839+dikshant-infracloud@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:54:08 +0530 Subject: [PATCH 083/101] Update deploy-cloud-run-grafana.yaml --- .github/workflows/deploy-cloud-run-grafana.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-cloud-run-grafana.yaml b/.github/workflows/deploy-cloud-run-grafana.yaml index 504c38258d582..e8b7e661fb54b 100644 --- a/.github/workflows/deploy-cloud-run-grafana.yaml +++ b/.github/workflows/deploy-cloud-run-grafana.yaml @@ -44,5 +44,5 @@ jobs: rm -rf /tmp/.buildx-cache mv /tmp/.buildx-cache-new /tmp/.buildx-cache - # - name: Deploy to Cloud Run - # run: gcloud run deploy db-api-server --image gcr.io/coderabbit/db-api-server --region us-central1 --allow-unauthenticated --vpc-connector=coderabbitai-dev-cr + - name: Deploy to Cloud Run + run: gcloud run deploy grafana --image gcr.io/coderabbit/grafana:latest --region us-central1 --allow-unauthenticated --vpc-connector=coderabbitai-dev-cr From 044a72007809776fa47ffed66ed40ccf1501155b Mon Sep 17 00:00:00 2001 From: dikshant-infracloud <160205839+dikshant-infracloud@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:58:19 +0530 Subject: [PATCH 084/101] Update deploy-cloud-run-grafana.yaml with CD --- .github/workflows/deploy-cloud-run-grafana.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/deploy-cloud-run-grafana.yaml b/.github/workflows/deploy-cloud-run-grafana.yaml index e8b7e661fb54b..13b74815feec6 100644 --- a/.github/workflows/deploy-cloud-run-grafana.yaml +++ b/.github/workflows/deploy-cloud-run-grafana.yaml @@ -36,8 +36,6 @@ jobs: tags: gcr.io/coderabbit/grafana:latest cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - build-contexts: | - mono=${{ github.workspace }} - name: Move Docker cache run: | From 0fcbc581f5c2b7c19f0ce7dc867969f8dde50ec2 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Wed, 31 Jul 2024 20:08:46 -0400 Subject: [PATCH 085/101] webpack fix for prod (#177) --- public/microfrontends/fn_dashboard/index.html | 27 +++---------------- .../views/index-microfrontend-template.html | 2 +- scripts/webpack/webpack.common.js | 1 - scripts/webpack/webpack.prod.js | 8 ++++-- 4 files changed, 11 insertions(+), 27 deletions(-) diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index fb0b659e1905e..4b8d921e535af 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -1,25 +1,6 @@ - - - - CodeRabbit Micro-frontend - - - - -
- - - - - - - - - + }; diff --git a/public/views/index-microfrontend-template.html b/public/views/index-microfrontend-template.html index 716020df9af66..edc4c0e7ff2f8 100644 --- a/public/views/index-microfrontend-template.html +++ b/public/views/index-microfrontend-template.html @@ -1,6 +1,6 @@ - + CodeRabbit Micro-frontend diff --git a/scripts/webpack/webpack.common.js b/scripts/webpack/webpack.common.js index 82adc1d17db0f..fe3f8e1ac2f3f 100644 --- a/scripts/webpack/webpack.common.js +++ b/scripts/webpack/webpack.common.js @@ -9,7 +9,6 @@ module.exports = { target: 'web', entry: { app: './public/app/index.ts', - fn_dashboard: './public/app/fn_dashboard.ts', }, output: { clean: true, diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 0e3ff4650888d..15d55615ce7b2 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -6,8 +6,7 @@ const { EsbuildPlugin } = require('esbuild-loader'); const { resolveToEsbuildTarget } = require('esbuild-plugin-browserslist'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); -const { EnvironmentPlugin } = require('webpack'); -const WebpackAssetsManifest = require('webpack-assets-manifest'); +const { DefinePlugin } = require('webpack'); const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); const { merge } = require('webpack-merge'); @@ -95,6 +94,11 @@ module.exports = (env = {}) => excludeChunks: ['dark', 'light', 'app'], }), new HTMLWebpackCSSChunks(), + new DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('development'), + }, + }), new WebpackManifestPlugin({ fileName: path.join(process.cwd(), 'manifest.json'), filter: (file) => !file.name.endsWith('.map'), From 64f0dc5feb27eff1e4759448b5bacafe281c6a69 Mon Sep 17 00:00:00 2001 From: dikshant-infracloud <160205839+dikshant-infracloud@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:37:24 +0530 Subject: [PATCH 086/101] added GH for prod (#178) Co-authored-by: dikshant --- .../deploy-cloud-run-grafana-prod.yaml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/deploy-cloud-run-grafana-prod.yaml diff --git a/.github/workflows/deploy-cloud-run-grafana-prod.yaml b/.github/workflows/deploy-cloud-run-grafana-prod.yaml new file mode 100644 index 0000000000000..8d667adc0c859 --- /dev/null +++ b/.github/workflows/deploy-cloud-run-grafana-prod.yaml @@ -0,0 +1,46 @@ +name: Deploy Grafana Server Cloud Run + +on: + push: + branches: + - fluxninja_micro_frontends + paths: + - "/**" + workflow_dispatch: + +jobs: + build_and_deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ secrets.GOOGLECLOUDSA_PROD }} + + - uses: docker/setup-buildx-action@v3 + + - name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-${{ github.workflow }}-${{ github.sha }} + restore-keys: ${{ runner.os }}-${{ github.workflow }}- + + - run: gcloud auth configure-docker + + - uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: gcr.io/coderabbitprod/grafana:latest + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + + - name: Move Docker cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache + + # - name: Deploy to Cloud Run + # run: gcloud run deploy grafana --image gcr.io/coderabbit/grafana:latest --region us-central1 --allow-unauthenticated --vpc-connector=coderabbitai-dev-cr From da4aad92bdd3e5985a4adcd77247f8dda985c4ba Mon Sep 17 00:00:00 2001 From: dikshant-infracloud <160205839+dikshant-infracloud@users.noreply.github.com> Date: Thu, 1 Aug 2024 18:32:48 +0530 Subject: [PATCH 087/101] Deploy grafana image to cloud run --- .github/workflows/deploy-cloud-run-grafana-prod.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-cloud-run-grafana-prod.yaml b/.github/workflows/deploy-cloud-run-grafana-prod.yaml index 8d667adc0c859..09f0b75dc804e 100644 --- a/.github/workflows/deploy-cloud-run-grafana-prod.yaml +++ b/.github/workflows/deploy-cloud-run-grafana-prod.yaml @@ -1,4 +1,4 @@ -name: Deploy Grafana Server Cloud Run +name: Deploy Grafana Server Cloud Run on prod on: push: @@ -42,5 +42,5 @@ jobs: rm -rf /tmp/.buildx-cache mv /tmp/.buildx-cache-new /tmp/.buildx-cache - # - name: Deploy to Cloud Run - # run: gcloud run deploy grafana --image gcr.io/coderabbit/grafana:latest --region us-central1 --allow-unauthenticated --vpc-connector=coderabbitai-dev-cr + - name: Deploy to Cloud Run + run: gcloud run deploy grafana --image gcr.io/coderabbitprod/grafana:latest --region us-central1 --allow-unauthenticated --vpc-connector=coderabbitaiprod-prod-cr From 732f2085c97bf813b8845dfaa03f9c6dc20befab Mon Sep 17 00:00:00 2001 From: dikshant-infracloud <160205839+dikshant-infracloud@users.noreply.github.com> Date: Thu, 1 Aug 2024 18:46:29 +0530 Subject: [PATCH 088/101] Update deploy-cloud-run-grafana-prod.yaml --- .github/workflows/deploy-cloud-run-grafana-prod.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-cloud-run-grafana-prod.yaml b/.github/workflows/deploy-cloud-run-grafana-prod.yaml index 09f0b75dc804e..aa0bd33946e73 100644 --- a/.github/workflows/deploy-cloud-run-grafana-prod.yaml +++ b/.github/workflows/deploy-cloud-run-grafana-prod.yaml @@ -43,4 +43,4 @@ jobs: mv /tmp/.buildx-cache-new /tmp/.buildx-cache - name: Deploy to Cloud Run - run: gcloud run deploy grafana --image gcr.io/coderabbitprod/grafana:latest --region us-central1 --allow-unauthenticated --vpc-connector=coderabbitaiprod-prod-cr + run: gcloud run deploy grafana-internal --image gcr.io/coderabbitprod/grafana:latest --region us-central1 --allow-unauthenticated --vpc-connector=coderabbitaiprod-prod-cr From 81b96c2370e6a657a405eea858a91388ca3ef351 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Thu, 8 Aug 2024 15:44:23 -0400 Subject: [PATCH 089/101] dashboard style changes (#179) --- .../grafana-data/src/themes/createColors.ts | 2 +- .../grafana-data/src/themes/createShape.ts | 2 +- .../TimeRangePicker/TimePickerContent.tsx | 73 +++++++-------- .../TimeRangePicker/TimePickerFooter.tsx | 77 ++++++++-------- .../dashboard/dashgrid/DashboardGrid.tsx | 2 + public/microfrontends/fn_dashboard/index.html | 16 +++- public/sass/_variables.generated.scss | 6 +- public/sass/_variables.light.generated.scss | 20 ++--- public/sass/pages/_dashboard.scss | 90 +++++++++++++++++++ 9 files changed, 196 insertions(+), 92 deletions(-) create mode 100644 public/sass/pages/_dashboard.scss diff --git a/packages/grafana-data/src/themes/createColors.ts b/packages/grafana-data/src/themes/createColors.ts index 2b02ddfb21611..0e125130d6631 100644 --- a/packages/grafana-data/src/themes/createColors.ts +++ b/packages/grafana-data/src/themes/createColors.ts @@ -220,7 +220,7 @@ class LightColors implements ThemeColorsBase> { }; background = { - primary: '#FAFAFA', + primary: '#FFFFFF', canvas: '#FFFFFF', secondary: '#FAFAFA', }; diff --git a/packages/grafana-data/src/themes/createShape.ts b/packages/grafana-data/src/themes/createShape.ts index 881633523f4b5..a9159087f05c0 100644 --- a/packages/grafana-data/src/themes/createShape.ts +++ b/packages/grafana-data/src/themes/createShape.ts @@ -19,7 +19,7 @@ export interface ThemeShapeInput { } export function createShape(options: ThemeShapeInput): ThemeShape { - const baseBorderRadius = options.borderRadius ?? 2; + const baseBorderRadius = options.borderRadius ?? 6; const radius = { default: '2px', diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx index cc23eb52f69f0..0da4357649f9b 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx @@ -277,42 +277,43 @@ const useTimeOption = (raw: RawTimeRange, quickOptions: TimeOption[]): TimeOptio const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRanges, isContainerTall, isFullscreen) => { return { - container: css` - background: ${theme.colors.background.primary}; - box-shadow: ${theme.shadows.z3}; - position: absolute; - z-index: ${theme.zIndex.dropdown}; - width: ${isFullscreen ? '546px' : '262px'}; - top: 116%; - border-radius: 2px; - border: 1px solid ${theme.colors.border.weak}; - ${isReversed ? 'left' : 'right'}: 0; - `, - body: css` - display: flex; - flex-direction: row-reverse; - height: ${isContainerTall ? '281px' : '217px'}; - `, - leftSide: css` - display: flex; - flex-direction: column; - border-right: ${isReversed ? 'none' : `1px solid ${theme.colors.border.weak}`}; - width: ${!hideQuickRanges ? '50%' : '100%'}; - overflow: auto; - order: ${isReversed ? 1 : 0}; - `, - rightSide: css` - width: ${isFullscreen ? '50%' : '100%'}; !important; - border-right: ${isReversed ? `1px solid ${theme.colors.border.weak}` : 'none'}; - display: flex; - flex-direction: column; - `, - timeRangeFilter: css` - padding: ${theme.spacing(1)}; - `, - spacing: css` - margin-top: 16px; - `, + container: css({ + background: theme.colors.background.primary, + boxShadow: theme.shadows.z3, + width: `${isFullscreen ? '546px' : '262px'}`, + borderRadius: '6px', + border: `1px solid ${theme.colors.border.weak}`, + [`${isReversed ? 'left' : 'right'}`]: 0, + }), + body: css({ + display: 'flex', + flexDirection: 'row-reverse', + height: `${isContainerTall ? '281px' : '217px'}`, + maxHeight: '100vh', + '& button': { + borderRadius: '6px', + }, + }), + 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', + }), }; }); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx index c8ef511d31163..51a2613ca7d60 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx @@ -166,43 +166,44 @@ export const TimePickerFooter = (props: Props) => { const getStyle = stylesFactory((theme: GrafanaTheme2) => { return { - container: css` - border-top: 1px solid ${theme.colors.border.weak}; - padding: 11px; - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - height: 60px; - `, - editContainer: css` - border-top: 1px solid ${theme.colors.border.weak}; - padding: 11px; - justify-content: space-between; - align-items: center; - padding: 7px; - `, - spacer: css` - margin-left: 7px; - `, - timeSettingContainer: css` - padding-top: ${theme.spacing(1)}; - `, - fiscalYearField: css` - margin-bottom: 0px; - `, - timeZoneContainer: css` - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - flex-grow: 1; - `, - timeZone: css` - display: flex; - flex-direction: row; - align-items: baseline; - flex-grow: 1; - `, + container: css({ + borderTop: `1px solid ${theme.colors.border.weak}`, + padding: '11px', + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + '& button': { + borderRadius: '6px', + }, + }), + 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/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index 252381314fee4..be44fe674ee45 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -153,6 +153,8 @@ export class Component extends PureComponent { this.gridWidth = gridWidth; } + console.log('this.props.dashboard.panels', config.theme2.shape.radius.default); + for (const panel of this.props.dashboard.panels) { const panelClasses = classNames({ 'react-grid-item--fullscreen': panel.isViewing }); diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index 4b8d921e535af..0fb4cc3cdf394 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -1,6 +1,16 @@ -CodeRabbit Micro-frontend
diff --git a/public/sass/_variables.generated.scss b/public/sass/_variables.generated.scss index 5edafebf856f9..af4b049cb217d 100644 --- a/public/sass/_variables.generated.scss +++ b/public/sass/_variables.generated.scss @@ -132,9 +132,9 @@ $headings-line-height: 1.5 !default; $border-width: 1px !default; -$border-radius: 2px !default; -$border-radius-lg: 6px !default; -$border-radius-sm: 2px !default; +$border-radius: 6px !default; +$border-radius-lg: 18px !default; +$border-radius-sm: 6px !default; // Page diff --git a/public/sass/_variables.light.generated.scss b/public/sass/_variables.light.generated.scss index ca5a3930e6516..8be386b389570 100644 --- a/public/sass/_variables.light.generated.scss +++ b/public/sass/_variables.light.generated.scss @@ -58,7 +58,7 @@ $gray-7: #fbfbfb; $white: #ffffff; $layer0: #FFFFFF; -$layer1: #FAFAFA; +$layer1: #FFFFFF; $layer2: #FAFAFA; $divider: rgba(45, 51, 62, 0.12); @@ -128,7 +128,7 @@ $hr-border-color: $gray-4 !default; // Panel // ------------------------- -$panel-bg: #FAFAFA; +$panel-bg: #FFFFFF; $panel-border: 1px solid rgba(45, 51, 62, 0.12); $panel-header-hover-bg: rgba(45, 51, 62, 0.12); $panel-box-shadow: none; @@ -145,7 +145,7 @@ $divider-border-color: $gray-2; $tight-form-func-bg: #FAFAFA; $tight-form-func-highlight-bg: #f5f5f5; -$modal-backdrop-bg: #FAFAFA; +$modal-backdrop-bg: #FFFFFF; $code-tag-bg: $gray-6; $code-tag-border: $gray-4; @@ -170,8 +170,8 @@ $scrollbarBorder: $gray-7; // ------------------------- $table-bg-accent: #FAFAFA; $table-border: rgba(45, 51, 62, 0.30); -$table-bg-odd: rgb(245, 245, 245); -$table-bg-hover: rgb(237, 237, 237); +$table-bg-odd: rgb(249, 249, 249); +$table-bg-hover: rgb(242, 242, 242); // Buttons // ------------------------- @@ -207,7 +207,7 @@ $btn-active-box-shadow: 0px 0px 4px rgba(234, 161, 51, 0.6); // Forms // ------------------------- -$input-bg: #FAFAFA; +$input-bg: #FFFFFF; $input-bg-disabled: rgba(45, 51, 62, 0.04); $input-color: #101828; @@ -229,7 +229,7 @@ $typeahead-selected-color: $yellow; // Dropdowns // ------------------------- -$dropdownBackground: #FAFAFA; +$dropdownBackground: #FFFFFF; $dropdownBorder: rgba(45, 51, 62, 0.12); $dropdownDividerTop: rgba(45, 51, 62, 0.12); $dropdownDividerBottom: rgba(45, 51, 62, 0.12); @@ -263,7 +263,7 @@ $side-menu-header-color: #e9edf2; // Menu dropdowns // ------------------------- -$menu-dropdown-bg: #FAFAFA; +$menu-dropdown-bg: #FFFFFF; $menu-dropdown-hover-bg: rgba(45, 51, 62, 0.12); $menu-dropdown-shadow: 0px 13px 20px 1px rgba(24, 26, 27, 0.18); @@ -289,7 +289,7 @@ $tooltipArrowColor: #FAFAFA; $tooltipBackgroundError: #E0226E; $tooltipShadow: 0px 4px 8px rgba(24, 26, 27, 0.2); -$popover-bg: #FAFAFA; +$popover-bg: #FFFFFF; $popover-color: #101828; $popover-border-color: rgba(45, 51, 62, 0.12); $popover-header-bg: #FAFAFA; @@ -305,7 +305,7 @@ $popover-error-bg: $btn-danger-bg; $popover-help-bg: $tooltipBackground; $popover-help-color: $tooltipColor; -$popover-code-bg: #FAFAFA; +$popover-code-bg: #FFFFFF; $popover-code-boxshadow: 0 0 5px $gray60; // images diff --git a/public/sass/pages/_dashboard.scss b/public/sass/pages/_dashboard.scss new file mode 100644 index 0000000000000..022e8558a8478 --- /dev/null +++ b/public/sass/pages/_dashboard.scss @@ -0,0 +1,90 @@ +.panel { + height: 100%; +} + +.panel-height-helper { + display: block; + height: 100%; +} + +.panel-container { + background-color: $panel-bg; + border: $panel-border; + position: relative; + border-radius: 6px; + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + flex: 1 1 0; + box-shadow: $panel-box-shadow; + + &--transparent { + background-color: transparent; + border: 1px solid transparent; + box-shadow: none; + } + + &:hover { + .panel-menu-toggle { + visibility: visible; + transition: opacity 0.1s ease-in 0.2s; + opacity: 1; + } + } + + &--is-editing { + height: auto; + } + + &--absolute { + position: absolute; + } +} + +.panel-content { + padding: $panel-padding; + width: 100%; + flex-grow: 1; + contain: strict; + height: calc(100% - #{$panel-header-height}); + + &--no-padding { + padding: 0; + } +} + +div.flot-text { + color: $text-color !important; +} + +.dashboard-solo { + .footer, + .sidemenu { + display: none; + } +} + +.template-variable { + color: $variable; +} + +.panel-solo { + position: fixed; + bottom: 0; + right: 0; + margin: 0; + left: 0; + top: 0; + width: '100%'; + height: '100%'; + + .panel-container { + border: none; + } + + .panel-menu-toggle, + .panel-menu { + display: none; + } +} From 2a0d73e31cbdcb5604cc8efd6034acf2fd579958 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Fri, 9 Aug 2024 15:11:00 -0400 Subject: [PATCH 090/101] disabled drag for mfe (#180) --- public/app/features/dashboard/dashgrid/DashboardGrid.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index be44fe674ee45..252381314fee4 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -153,8 +153,6 @@ export class Component extends PureComponent { this.gridWidth = gridWidth; } - console.log('this.props.dashboard.panels', config.theme2.shape.radius.default); - for (const panel of this.props.dashboard.panels) { const panelClasses = classNames({ 'react-grid-item--fullscreen': panel.isViewing }); From 26f25e6900c4614def27f587e6c053d296e02f41 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Mon, 12 Aug 2024 14:53:21 -0400 Subject: [PATCH 091/101] changed error message to no data (#182) --- public/app/plugins/panel/barchart/utils.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/public/app/plugins/panel/barchart/utils.ts b/public/app/plugins/panel/barchart/utils.ts index 117d43e327aee..5d8192e260a24 100644 --- a/public/app/plugins/panel/barchart/utils.ts +++ b/public/app/plugins/panel/barchart/utils.ts @@ -539,10 +539,7 @@ function getRotationPadding( function getScaleOrientation(orientation: VizOrientation) { if (orientation === VizOrientation.Vertical) { return { - xOri: ScaleOrientation.Horizontal, - xDir: ScaleDirection.Right, - yOri: ScaleOrientation.Vertical, - yDir: ScaleDirection.Up, + warn: 'No Data', }; } From 355ae05c396f0c54bfd093cb0227a123181a90fc Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Tue, 27 Aug 2024 17:46:42 -0400 Subject: [PATCH 092/101] fix --- go.work.sum | 3 +- .../dashboard/dashgrid/DashboardPanel.tsx | 18 +- public/microfrontends/fn_dashboard/index.html | 117 ++++- public/sass/_variables.dark.generated.scss | 26 +- public/sass/_variables.generated.scss | 4 +- public/views/error.html | 161 ++++--- public/views/index.html | 442 ++++-------------- scripts/webpack/webpack.dev.js | 2 +- scripts/webpack/webpack.prod.js | 2 +- yarn.lock | 177 +++---- 10 files changed, 433 insertions(+), 519 deletions(-) diff --git a/go.work.sum b/go.work.sum index 448f00a3af11c..03dfc6d544274 100644 --- a/go.work.sum +++ b/go.work.sum @@ -526,7 +526,6 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/bradleyjkemp/cupaloy/v2 v2.6.0 h1:knToPYa2xtfg42U3I6punFEjaGFKWQRXJwj0JTv4mTs= github.com/bradleyjkemp/cupaloy/v2 v2.6.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= @@ -1204,6 +1203,7 @@ golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -1227,6 +1227,7 @@ google.golang.org/api v0.187.0/go.mod h1:KIHlTc4x7N7gKKuVsdmfBXN13yEEWXWFURWY6SB google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 h1:SeX3QUcBj3fciwnfPT9kt5gBhFy/FCZtYZ+I/RB8agc= google.golang.org/genproto v0.0.0-20240528184218-531527333157/go.mod h1:ubQlAQnzejB8uZzszhrTCU2Fyp6Vi7ZE5nn0c3W8+qQ= google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:s7iA721uChleev562UJO2OYB0PPT9CMFjV+Ce7VJH5M= google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index 1f4afad770c64..51f6410d6e6b7 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -34,7 +34,7 @@ const mapStateToProps = (state: StoreState, props: OwnProps) => { return { plugin: panelState.plugin, instanceState: panelState.instanceState, - fnGlobalState: state.fnGlobalState + fnGlobalState: state.fnGlobalState, }; }; @@ -47,7 +47,6 @@ const connector = connect(mapStateToProps, mapDispatchToProps); export type Props = OwnProps & ConnectedProps; export class DashboardPanelUnconnected extends PureComponent { - static defaultProps: Partial = { lazy: true, }; @@ -74,7 +73,18 @@ export class DashboardPanelUnconnected extends PureComponent { }; renderPanel = (isInView: boolean) => { - const { dashboard, panel, isViewing, isEditing, width, height, plugin, timezone, fnGlobalState, isDraggable = true } = this.props; + const { + dashboard, + panel, + isViewing, + isEditing, + width, + height, + plugin, + timezone, + fnGlobalState, + isDraggable = true, + } = this.props; // console.log(this.props, "on render panel") @@ -125,7 +135,7 @@ export class DashboardPanelUnconnected extends PureComponent { {this.renderPanel} ) : ( - this.renderPanel({ isInView: true }) + this.renderPanel(true) ); } } diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index 0fb4cc3cdf394..90b98aa760463 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -1,16 +1,101 @@ - - - - CodeRabbit Micro-frontend - - - - -
- +Html Webpack Plugin: +
+  Error: Child compilation failed:
+  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
+  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
+  
+  - Compilation.js:2094 
+    [grafana]/[webpack]/lib/Compilation.js:2094:28
+  
+  - NormalModuleFactory.js:895 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
+  
+  
+  - NormalModuleFactory.js:332 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
+  
+  
+  - NormalModuleFactory.js:509 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
+  
+  - NormalModuleFactory.js:151 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
+  
+  - NormalModuleFactory.js:767 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
+  
+  - NormalModuleFactory.js:979 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
+  
+  - NormalModuleFactory.js:1109 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
+  
+  - Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  
+  - ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  
+  - Compilation.js:2094 
+    [grafana]/[webpack]/lib/Compilation.js:2094:28
+  
+  - NormalModuleFactory.js:895 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
+  
+  
+  - NormalModuleFactory.js:332 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
+  
+  
+  - NormalModuleFactory.js:509 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
+  
+  - NormalModuleFactory.js:151 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
+  
+  - NormalModuleFactory.js:767 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
+  
+  - NormalModuleFactory.js:979 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
+  
+  - NormalModuleFactory.js:1109 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
+  
+  - child-compiler.js:174 
+    [grafana]/[html-webpack-plugin]/lib/child-compiler.js:174:18
+  
+  - Compiler.js:605 finalCallback
+    [grafana]/[webpack]/lib/Compiler.js:605:5
+  
+  - Compiler.js:640 
+    [grafana]/[webpack]/lib/Compiler.js:640:11
+  
+  - Compiler.js:1329 
+    [grafana]/[webpack]/lib/Compiler.js:1329:17
+  
+  
+  - task_queues:95 process.processTicksAndRejections
+    node:internal/process/task_queues:95:5
+  
+
\ No newline at end of file diff --git a/public/sass/_variables.dark.generated.scss b/public/sass/_variables.dark.generated.scss index 22dbb1b05cc12..6a3bb0f0580e0 100644 --- a/public/sass/_variables.dark.generated.scss +++ b/public/sass/_variables.dark.generated.scss @@ -65,10 +65,10 @@ $layer0: #312D2B; $layer1: #3B3835; $layer2: #5E5855; -$divider: rgba(219, 217, 215, 0.07); +$divider: rgba(219, 217, 215, 0.12); -$border0: rgba(219, 217, 215, 0.07); -$border1: rgba(219, 217, 215, 0.15); +$border0: rgba(219, 217, 215, 0.12); +$border1: rgba(219, 217, 215, 0.20); // Accent colors // ------------------------- @@ -134,7 +134,7 @@ $hr-border-color: $dark-9; // Panel // ------------------------- $panel-bg: #3B3835; -$panel-border: 1px solid rgba(219, 217, 215, 0.07); +$panel-border: 1px solid rgba(219, 217, 215, 0.12); $panel-header-hover-bg: rgba(219, 217, 215, 0.16); $panel-box-shadow: none; $panel-corner: $panel-bg; @@ -174,7 +174,7 @@ $scrollbarBorder: black; // Tables // ------------------------- $table-bg-accent: #5E5855; -$table-border: rgba(219, 217, 215, 0.15); +$table-border: rgba(219, 217, 215, 0.20); $table-bg-odd: rgb(62, 59, 57); $table-bg-hover: rgb(68, 65, 63); @@ -216,7 +216,7 @@ $input-bg: #312D2B; $input-bg-disabled: rgba(219, 217, 215, 0.04); $input-color: #DBD9D7; -$input-border-color: rgba(219, 217, 215, 0.15); +$input-border-color: rgba(219, 217, 215, 0.20); $input-box-shadow: none; $input-border-focus: #ffffff00; $input-box-shadow-focus: #ffffff00 !default; @@ -235,10 +235,10 @@ $typeahead-selected-color: $yellow; // Dropdowns // ------------------------- $dropdownBackground: #3B3835; -$dropdownBorder: rgba(219, 217, 215, 0.07); -$dropdownDividerTop: rgba(219, 217, 215, 0.07); -$dropdownDividerBottom: rgba(219, 217, 215, 0.07); -$dropdownShadow: 0px 8px 24px rgb(1,4,9); +$dropdownBorder: rgba(219, 217, 215, 0.12); +$dropdownDividerTop: rgba(219, 217, 215, 0.12); +$dropdownDividerBottom: rgba(219, 217, 215, 0.12); +$dropdownShadow: 0px 8px 24px rgb(1, 4, 9); $dropdownLinkColor: $link-color; $dropdownLinkColorHover: $white; @@ -268,7 +268,7 @@ $side-menu-header-color: #DBD9D7; // ------------------------- $menu-dropdown-bg: #3B3835; $menu-dropdown-hover-bg: rgba(219, 217, 215, 0.16); -$menu-dropdown-shadow: 0px 8px 24px rgb(1,4,9); +$menu-dropdown-shadow: 0px 8px 24px rgb(1, 4, 9); // Tabs // ------------------------- @@ -300,9 +300,9 @@ $tooltipShadow: 0px 4px 8px rgba(1, 4, 9, 0.75); $popover-bg: #3B3835; $popover-color: #DBD9D7; -$popover-border-color: rgba(219, 217, 215, 0.07); +$popover-border-color: rgba(219, 217, 215, 0.12); $popover-header-bg: #5E5855; -$popover-shadow: 0px 8px 24px rgb(1,4,9); +$popover-shadow: 0px 8px 24px rgb(1, 4, 9); $popover-help-bg: $tooltipBackground; $popover-help-color: $text-color; diff --git a/public/sass/_variables.generated.scss b/public/sass/_variables.generated.scss index af4b049cb217d..ee0561eb84645 100644 --- a/public/sass/_variables.generated.scss +++ b/public/sass/_variables.generated.scss @@ -132,9 +132,9 @@ $headings-line-height: 1.5 !default; $border-width: 1px !default; -$border-radius: 6px !default; +$border-radius: 2px !default; $border-radius-lg: 18px !default; -$border-radius-sm: 6px !default; +$border-radius-sm: 2px !default; // Page diff --git a/public/views/error.html b/public/views/error.html index 1eb195cd125b9..90b98aa760463 100644 --- a/public/views/error.html +++ b/public/views/error.html @@ -1,60 +1,101 @@ - - - - - - - - - [[.AppTitle]] - Error - - - - [[ if eq .ThemeType "light" ]] - - [[ else ]] - - [[ end ]] - - - - - - -
-
- -
-
-
-
-
-
[[.Title]]
-
-
-
- [[if .ErrorMsg]] -

Error details

-
-
[[.ErrorMsg]]
-
- [[end]] -
-

Check the Grafana server logs for the detailed error message.

-
-
-
- - +Html Webpack Plugin: +
+  Error: Child compilation failed:
+  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
+  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
+  
+  - Compilation.js:2094 
+    [grafana]/[webpack]/lib/Compilation.js:2094:28
+  
+  - NormalModuleFactory.js:895 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
+  
+  
+  - NormalModuleFactory.js:332 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
+  
+  
+  - NormalModuleFactory.js:509 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
+  
+  - NormalModuleFactory.js:151 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
+  
+  - NormalModuleFactory.js:767 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
+  
+  - NormalModuleFactory.js:979 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
+  
+  - NormalModuleFactory.js:1109 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
+  
+  - Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  
+  - ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  
+  - Compilation.js:2094 
+    [grafana]/[webpack]/lib/Compilation.js:2094:28
+  
+  - NormalModuleFactory.js:895 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
+  
+  
+  - NormalModuleFactory.js:332 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
+  
+  
+  - NormalModuleFactory.js:509 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
+  
+  - NormalModuleFactory.js:151 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
+  
+  - NormalModuleFactory.js:767 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
+  
+  - NormalModuleFactory.js:979 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
+  
+  - NormalModuleFactory.js:1109 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
+  
+  - child-compiler.js:174 
+    [grafana]/[html-webpack-plugin]/lib/child-compiler.js:174:18
+  
+  - Compiler.js:605 finalCallback
+    [grafana]/[webpack]/lib/Compiler.js:605:5
+  
+  - Compiler.js:640 
+    [grafana]/[webpack]/lib/Compiler.js:640:11
+  
+  - Compiler.js:1329 
+    [grafana]/[webpack]/lib/Compiler.js:1329:17
+  
+  
+  - task_queues:95 process.processTicksAndRejections
+    node:internal/process/task_queues:95:5
+  
+
\ No newline at end of file diff --git a/public/views/index.html b/public/views/index.html index 3bf6889f52070..90b98aa760463 100644 --- a/public/views/index.html +++ b/public/views/index.html @@ -1,341 +1,101 @@ - - - - [[ if and .CSPEnabled .IsDevelopmentEnv ]] - - - [[ end ]] - - - - - - [[.AppTitle]] - - - - - - - - - [[ if eq .ThemeType "light" ]] - - [[ else if eq .ThemeType "dark" ]] - - [[ end ]] - - - - - - - - - - - - -
-
-
- -
-
-
-

- If you're seeing this Grafana has failed to load its application files -
-
-

-

- 1. This could be caused by your reverse proxy settings.

- 2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath. If not - using a reverse proxy make sure to set serve_from_sub_path to true.
-
- 3. If you have a local dev build make sure you build frontend using: yarn start, or yarn build
-
- 4. Sometimes restarting grafana-server can help
-
- 5. Check if you are using a non-supported browser. For more information, refer to the list of - - supported browsers. -

-
- -
- -
- - - - [[if .GoogleTagManagerId]] - - - - - - [[end]] - - [[range $asset := .Assets.JSFiles]] - - [[end]] - - - - +Html Webpack Plugin: +
+  Error: Child compilation failed:
+  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
+  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
+      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
+      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
+  
+  - Compilation.js:2094 
+    [grafana]/[webpack]/lib/Compilation.js:2094:28
+  
+  - NormalModuleFactory.js:895 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
+  
+  
+  - NormalModuleFactory.js:332 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
+  
+  
+  - NormalModuleFactory.js:509 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
+  
+  - NormalModuleFactory.js:151 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
+  
+  - NormalModuleFactory.js:767 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
+  
+  - NormalModuleFactory.js:979 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
+  
+  - NormalModuleFactory.js:1109 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
+  
+  - Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  
+  - ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
+  
+  - Compilation.js:2094 
+    [grafana]/[webpack]/lib/Compilation.js:2094:28
+  
+  - NormalModuleFactory.js:895 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
+  
+  
+  - NormalModuleFactory.js:332 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
+  
+  
+  - NormalModuleFactory.js:509 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
+  
+  - NormalModuleFactory.js:151 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
+  
+  - NormalModuleFactory.js:767 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
+  
+  - NormalModuleFactory.js:979 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
+  
+  - NormalModuleFactory.js:1109 
+    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
+  
+  - child-compiler.js:174 
+    [grafana]/[html-webpack-plugin]/lib/child-compiler.js:174:18
+  
+  - Compiler.js:605 finalCallback
+    [grafana]/[webpack]/lib/Compiler.js:605:5
+  
+  - Compiler.js:640 
+    [grafana]/[webpack]/lib/Compiler.js:640:11
+  
+  - Compiler.js:1329 
+    [grafana]/[webpack]/lib/Compiler.js:1329:17
+  
+  
+  - task_queues:95 process.processTicksAndRejections
+    node:internal/process/task_queues:95:5
+  
+
\ No newline at end of file diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index f20e9c0369d33..64243e6a60f01 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -4,6 +4,7 @@ const browserslist = require('browserslist'); const { resolveToEsbuildTarget } = require('esbuild-plugin-browserslist'); const ESLintPlugin = require('eslint-webpack-plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); const { DefinePlugin, EnvironmentPlugin } = require('webpack'); @@ -150,7 +151,6 @@ module.exports = (env = {}) => { chunksSortMode: 'none', excludeChunks: ['dark', 'light', 'app'], }), - new HTMLWebpackCSSChunks(), new DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development'), diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 15d55615ce7b2..8db24b7a6bbc7 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -4,6 +4,7 @@ const browserslist = require('browserslist'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const { EsbuildPlugin } = require('esbuild-loader'); const { resolveToEsbuildTarget } = require('esbuild-plugin-browserslist'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); const { DefinePlugin } = require('webpack'); @@ -93,7 +94,6 @@ module.exports = (env = {}) => chunksSortMode: 'none', excludeChunks: ['dark', 'light', 'app'], }), - new HTMLWebpackCSSChunks(), new DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development'), diff --git a/yarn.lock b/yarn.lock index 39765319e9fba..38872ab3bb0fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4939,8 +4939,8 @@ __metadata: linkType: hard "@mapbox/mapbox-gl-style-spec@npm:^13.23.1": - version: 13.27.0 - resolution: "@mapbox/mapbox-gl-style-spec@npm:13.27.0" + version: 13.25.0 + resolution: "@mapbox/mapbox-gl-style-spec@npm:13.25.0" dependencies: "@mapbox/jsonlint-lines-primitives": "npm:~2.0.2" "@mapbox/point-geometry": "npm:^0.1.0" @@ -5155,8 +5155,8 @@ __metadata: linkType: hard "@npmcli/fs@npm:^1.0.0": - version: 1.1.1 - resolution: "@npmcli/fs@npm:1.1.1" + version: 1.0.0 + resolution: "@npmcli/fs@npm:1.0.0" dependencies: "@gar/promisify": "npm:^1.0.1" semver: "npm:^7.3.5" @@ -9033,8 +9033,8 @@ __metadata: linkType: hard "@types/babel__generator@npm:*": - version: 7.6.4 - resolution: "@types/babel__generator@npm:7.6.4" + version: 7.6.3 + resolution: "@types/babel__generator@npm:7.6.3" dependencies: "@babel/types": "npm:^7.0.0" checksum: 10/11a6fb83c3f9eb6ce19eebfd64e1d558aa445ca7c8c6db3e7760ade517b8734a18cf500e238058ca09ae8486a6350e1071f826f38a5a233ccfc5dd2a009340b3 @@ -9068,8 +9068,8 @@ __metadata: linkType: hard "@types/body-parser@npm:*": - version: 1.19.2 - resolution: "@types/body-parser@npm:1.19.2" + version: 1.19.1 + resolution: "@types/body-parser@npm:1.19.1" dependencies: "@types/connect": "npm:*" "@types/node": "npm:*" @@ -9143,8 +9143,8 @@ __metadata: linkType: hard "@types/d3-axis@npm:*": - version: 3.0.2 - resolution: "@types/d3-axis@npm:3.0.2" + version: 3.0.1 + resolution: "@types/d3-axis@npm:3.0.1" dependencies: "@types/d3-selection": "npm:*" checksum: 10/2d321c4f4169d9fdc8a17cca00d1581a2f7e65d7a79f29da055579cc3e9e0809ea28f4578fe2b835d008278ab4e106c694ea4de1da0a35cbe609691537ac2efc @@ -9152,8 +9152,8 @@ __metadata: linkType: hard "@types/d3-brush@npm:*": - version: 3.0.2 - resolution: "@types/d3-brush@npm:3.0.2" + version: 3.0.1 + resolution: "@types/d3-brush@npm:3.0.1" dependencies: "@types/d3-selection": "npm:*" checksum: 10/a77f31cb99d1e00950ab2da9319dad33aea7c0f432ded468070799b24c3839fbb189f2f73562f008b02e5a7c4c5e3f14b4bd1650750223dc6637a6283448ad77 @@ -9175,8 +9175,8 @@ __metadata: linkType: hard "@types/d3-contour@npm:*": - version: 3.0.2 - resolution: "@types/d3-contour@npm:3.0.2" + version: 3.0.1 + resolution: "@types/d3-contour@npm:3.0.1" dependencies: "@types/d3-array": "npm:*" "@types/geojson": "npm:*" @@ -9199,8 +9199,8 @@ __metadata: linkType: hard "@types/d3-drag@npm:*": - version: 3.0.2 - resolution: "@types/d3-drag@npm:3.0.2" + version: 3.0.1 + resolution: "@types/d3-drag@npm:3.0.1" dependencies: "@types/d3-selection": "npm:*" checksum: 10/7bae2779d127fec2d384bab2cbb07c19102a2d51c72093cdd1a815e74448a077822544d3617f3d7fc3b7c0a7a2829693431ba7db03d1ac61662a71b21b2eee5a @@ -9222,8 +9222,8 @@ __metadata: linkType: hard "@types/d3-fetch@npm:*": - version: 3.0.2 - resolution: "@types/d3-fetch@npm:3.0.2" + version: 3.0.1 + resolution: "@types/d3-fetch@npm:3.0.1" dependencies: "@types/d3-dsv": "npm:*" checksum: 10/4369842d970b06079ff43a4c7384e454776b5fef42b445f78021e078413d0cb5b11408f30cdc4db3e674419d1b7cccd178fd70faf5177f8df5ec89ae39f62f53 @@ -9337,8 +9337,8 @@ __metadata: linkType: hard "@types/d3-shape@npm:*": - version: 3.1.1 - resolution: "@types/d3-shape@npm:3.1.1" + version: 3.0.2 + resolution: "@types/d3-shape@npm:3.0.2" dependencies: "@types/d3-path": "npm:*" checksum: 10/43a6b73d539679a5c672fb63f4e7063517c39aad74e30b17aacce1802b3c24207a8d824584164a33d7c2ccae84a774dc9f767ec95e4e38afb7d8b11cee9e3c65 @@ -9383,8 +9383,8 @@ __metadata: linkType: hard "@types/d3-transition@npm:*": - version: 3.0.3 - resolution: "@types/d3-transition@npm:3.0.3" + version: 3.0.1 + resolution: "@types/d3-transition@npm:3.0.1" dependencies: "@types/d3-selection": "npm:*" checksum: 10/2f9d11d40c7560d8cb6163e579bebf5781285589dd9812fb050772ff376250457e715f764f6d3edff0cf91f23df4e23d43cd34b4ca740391d2557628aadfac69 @@ -9392,8 +9392,8 @@ __metadata: linkType: hard "@types/d3-zoom@npm:*": - version: 3.0.2 - resolution: "@types/d3-zoom@npm:3.0.2" + version: 3.0.1 + resolution: "@types/d3-zoom@npm:3.0.1" dependencies: "@types/d3-interpolate": "npm:*" "@types/d3-selection": "npm:*" @@ -11312,7 +11312,7 @@ __metadata: languageName: node linkType: hard -"abbrev@npm:1, abbrev@npm:^1.0.0": +"abbrev@npm:1": version: 1.1.1 resolution: "abbrev@npm:1.1.1" checksum: 10/2d882941183c66aa665118bafdab82b7a177e9add5eb2776c33e960a4f3c89cff88a1b38aba13a456de01d0dd9d66a8bea7c903268b21ea91dd1097e1e2e8243 @@ -13443,13 +13443,6 @@ __metadata: languageName: node linkType: hard -"colors@npm:1.0.3": - version: 1.0.3 - resolution: "colors@npm:1.0.3" - checksum: 234e8d3ab7e4003851cdd6a1f02eaa16dabc502ee5f4dc576ad7959c64b7477b15bd21177bab4055a4c0a66aa3d919753958030445f87c39a253d73b7a3637f5 - languageName: node - linkType: hard - "colors@npm:1.4.0": version: 1.4.0 resolution: "colors@npm:1.4.0" @@ -13941,9 +13934,9 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^7, cosmiconfig@npm:^7.0.0, cosmiconfig@npm:^7.0.1": - version: 7.1.0 - resolution: "cosmiconfig@npm:7.1.0" +"cosmiconfig@npm:^7.0.0, cosmiconfig@npm:^7.0.1": + version: 7.0.1 + resolution: "cosmiconfig@npm:7.0.1" dependencies: "@types/parse-json": "npm:^4.0.0" import-fresh: "npm:^3.2.1" @@ -14220,8 +14213,8 @@ __metadata: linkType: hard "css-select@npm:^4.1.3": - version: 4.3.0 - resolution: "css-select@npm:4.3.0" + version: 4.1.3 + resolution: "css-select@npm:4.1.3" dependencies: boolbase: "npm:^1.0.0" css-what: "npm:^5.0.0" @@ -15178,8 +15171,8 @@ __metadata: linkType: hard "defaults@npm:^1.0.3": - version: 1.0.4 - resolution: "defaults@npm:1.0.4" + version: 1.0.3 + resolution: "defaults@npm:1.0.3" dependencies: clone: "npm:^1.0.2" checksum: 10/96e2112da6553d376afd5265ea7cbdb2a3b45535965d71ab8bb1da10c8126d168fdd5268799625324b368356d21ba2a7b3d4ec50961f11a47b7feb9de3d4413e @@ -15529,9 +15522,9 @@ __metadata: languageName: node linkType: hard -"domhandler@npm:^4.0.0, domhandler@npm:^4.2.0, domhandler@npm:^4.3.1": - version: 4.3.1 - resolution: "domhandler@npm:4.3.1" +"domhandler@npm:^4.0.0, domhandler@npm:^4.2.0": + version: 4.2.2 + resolution: "domhandler@npm:4.2.2" dependencies: domelementtype: "npm:^2.2.0" checksum: 10/502cb297ba7b5a369c944dd2ecde1acd63992929d3f24b2dbd66a65cd6cfc21c5d2f237b0c68d4ec03d4224b1d70b511f04f4423f9aab42777488ee88c98e7e6 @@ -15918,8 +15911,8 @@ __metadata: linkType: hard "error-stack-parser@npm:^2.0.6": - version: 2.1.4 - resolution: "error-stack-parser@npm:2.1.4" + version: 2.0.6 + resolution: "error-stack-parser@npm:2.0.6" dependencies: stackframe: "npm:^1.1.1" checksum: 10/c83a0f425b73ed8bae4b05535f76477fdd4421e2cca398a2051719ac7eb5f918622d6313ef24f6ab6f64cbd38ebd1119bcb15cd792befbf2dd472d02062ff6d8 @@ -17332,8 +17325,8 @@ __metadata: linkType: hard "fb-watchman@npm:^2.0.0": - version: 2.0.2 - resolution: "fb-watchman@npm:2.0.2" + version: 2.0.1 + resolution: "fb-watchman@npm:2.0.1" dependencies: bser: "npm:2.1.1" checksum: 10/9a03efc7d41ce3ca3d799d63505a1f7312caddf4e7737d39f2165bfe4872cbd4b87eccc9e6c57229ea08f14b4d7187896da31a7270b8da7a4aaa8fba2d3d1c42 @@ -17488,7 +17481,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^2.0.0": +"find-up@npm:^2.0.0, find-up@npm:^2.1.0": version: 2.1.0 resolution: "find-up@npm:2.1.0" dependencies: @@ -19153,8 +19146,8 @@ __metadata: linkType: hard "html-minifier-terser@npm:^6.0.2": - version: 6.1.0 - resolution: "html-minifier-terser@npm:6.1.0" + version: 6.0.2 + resolution: "html-minifier-terser@npm:6.0.2" dependencies: camel-case: "npm:^4.1.2" clean-css: "npm:^5.1.5" @@ -19361,8 +19354,8 @@ __metadata: linkType: hard "http-proxy-middleware@npm:^2.0.3": - version: 2.0.6 - resolution: "http-proxy-middleware@npm:2.0.6" + version: 2.0.4 + resolution: "http-proxy-middleware@npm:2.0.4" dependencies: "@types/http-proxy": "npm:^1.17.8" http-proxy: "npm:^1.18.1" @@ -19783,8 +19776,8 @@ __metadata: linkType: hard "intl-messageformat@npm:^10.1.0": - version: 10.2.5 - resolution: "intl-messageformat@npm:10.2.5" + version: 10.1.4 + resolution: "intl-messageformat@npm:10.1.4" dependencies: "@formatjs/ecma402-abstract": "npm:1.12.0" "@formatjs/fast-memoize": "npm:1.2.6" @@ -20211,8 +20204,8 @@ __metadata: linkType: hard "is-number-object@npm:^1.0.4": - version: 1.0.7 - resolution: "is-number-object@npm:1.0.7" + version: 1.0.6 + resolution: "is-number-object@npm:1.0.6" dependencies: has-tostringtag: "npm:^1.0.0" checksum: 10/d848fdc0fc69e30866b87fcaae17a3e68a8be669073ab3bf9a578c29106a2d5084089a2e7bc40819ec55eac94a52d9e20d735e7bfd3a46202b17199e555f91fa @@ -20924,8 +20917,8 @@ __metadata: linkType: hard "jest-pnp-resolver@npm:^1.2.2": - version: 1.2.3 - resolution: "jest-pnp-resolver@npm:1.2.3" + version: 1.2.2 + resolution: "jest-pnp-resolver@npm:1.2.2" peerDependencies: jest-resolve: "*" peerDependenciesMeta: @@ -21604,8 +21597,8 @@ __metadata: linkType: hard "keycon@npm:^1.2.0": - version: 1.4.0 - resolution: "keycon@npm:1.4.0" + version: 1.2.2 + resolution: "keycon@npm:1.2.2" dependencies: "@daybrush/utils": "npm:^1.7.1" "@scena/event-emitter": "npm:^1.0.2" @@ -22818,10 +22811,41 @@ __metadata: "merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 + resolution: "merge2@npm:1.4.1" checksum: 10/7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 languageName: node linkType: hard +"methods@npm:~1.1.2": + version: 1.1.2 + resolution: "methods@npm:1.1.2" + checksum: 10/a385dd974faa34b5dd021b2bbf78c722881bf6f003bfe6d391d7da3ea1ed625d1ff10ddd13c57531f628b3e785be38d3eed10ad03cebd90b76932413df9a1820 + languageName: node + linkType: hard + +"micro-memoize@npm:^4.1.2": + version: 4.1.2 + resolution: "micro-memoize@npm:4.1.2" + checksum: 10/027e90c3147c97c07224440ea50ede27eb7d888149e4925820397b466d16efc525f5ec3981e4cadec3258a8d36dfd5e7e7c8e660879fbe2e47106785be9bc570 + languageName: node + linkType: hard + +"micromark-core-commonmark@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-core-commonmark@npm:2.0.1" + dependencies: + decode-named-character-reference: "npm:^1.0.0" + devlop: "npm:^1.0.0" + micromark-factory-destination: "npm:^2.0.0" + micromark-factory-label: "npm:^2.0.0" + micromark-factory-space: "npm:^2.0.0" + micromark-factory-title: "npm:^2.0.0" + micromark-factory-whitespace: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-chunked: "npm:^2.0.0" + micromark-util-classify-character: "npm:^2.0.0" + micromark-util-html-tag-name: "npm:^2.0.0" + micromark-util-normalize-identifier: "npm:^2.0.0" micromark-util-resolve-all: "npm:^2.0.0" micromark-util-subtokenize: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" @@ -23595,8 +23619,8 @@ __metadata: linkType: hard "moo-color@npm:^1.0.2": - version: 1.0.3 - resolution: "moo-color@npm:1.0.3" + version: 1.0.2 + resolution: "moo-color@npm:1.0.2" dependencies: color-name: "npm:^1.1.4" checksum: 10/6dced73bfb3048d2a60e4c7e2a5c414c4e7877dac54283168715a891525819109141b40bd9a7fd28f878802b4e166bd0452be926bfb6c0ab95bf9ee2b84e1b3d @@ -24646,7 +24670,7 @@ __metadata: languageName: node linkType: hard -"ora@npm:^5.1.0, ora@npm:^5.4.1": +"ora@npm:^5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" dependencies: @@ -25370,13 +25394,6 @@ __metadata: languageName: node linkType: hard -"pofile@npm:^1.1.0": - version: 1.1.4 - resolution: "pofile@npm:1.1.4" - checksum: 7ef428d2793fcbcf021e4250d36043374ffbd7c8e15268977fae2361536abb894e97ee58525b2c1eeda5688a2b14b274657a271e08816059b12d8c02ac99fde0 - languageName: node - linkType: hard - "polished@npm:^4.2.2": version: 4.2.2 resolution: "polished@npm:4.2.2" @@ -27531,8 +27548,8 @@ __metadata: linkType: hard "react-use-measure@npm:^2.0.4": - version: 2.1.1 - resolution: "react-use-measure@npm:2.1.1" + version: 2.0.4 + resolution: "react-use-measure@npm:2.0.4" dependencies: debounce: "npm:^1.2.0" peerDependencies: @@ -28461,8 +28478,8 @@ __metadata: linkType: hard "rollup-plugin-node-externals@npm:^5.0.0": - version: 5.0.3 - resolution: "rollup-plugin-node-externals@npm:5.0.3" + version: 5.0.2 + resolution: "rollup-plugin-node-externals@npm:5.0.2" peerDependencies: rollup: ^2.60.0 || ^3.0.0 checksum: 10/65d24e6f174d170b855912f230e2dbb9debee4c81d2819e88391f324cc190a84f2c1ab4b421688145786df822434e40b6203524be497832b2f1201dc3728ef77 @@ -28868,7 +28885,7 @@ __metadata: languageName: node linkType: hard -"set-blocking@npm:^2.0.0": +"set-blocking@npm:^2.0.0, set-blocking@npm:~2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" checksum: 10/8980ebf7ae9eb945bb036b6e283c547ee783a1ad557a82babf758a065e2fb6ea337fd82cac30dd565c1e606e423f30024a19fff7afbf4977d784720c4026a8ef @@ -29702,8 +29719,8 @@ __metadata: linkType: hard "stack-generator@npm:^2.0.5": - version: 2.0.10 - resolution: "stack-generator@npm:2.0.10" + version: 2.0.5 + resolution: "stack-generator@npm:2.0.5" dependencies: stackframe: "npm:^1.1.1" checksum: 10/3c7b925c34b93f1528e334f1ed5fe4d7a5d4874589cb63ce539f569e9c76649037b7848be953b24f3c46865584425281fc51925e42c87b7fec128ad646ccae97 @@ -29720,8 +29737,8 @@ __metadata: linkType: hard "stack-utils@npm:^2.0.3": - version: 2.0.6 - resolution: "stack-utils@npm:2.0.6" + version: 2.0.5 + resolution: "stack-utils@npm:2.0.5" dependencies: escape-string-regexp: "npm:^2.0.0" checksum: 10/a6d64e5dd24d321289ebefdff2e210ece75fdf20dbcdb702b86da1f7b730743fae3e9337adae4a5cc00d4970d748ff758387df3ea7c71c45b466c43c7359bc00 @@ -29743,8 +29760,8 @@ __metadata: linkType: hard "stacktrace-gps@npm:^3.0.4": - version: 3.1.2 - resolution: "stacktrace-gps@npm:3.1.2" + version: 3.0.4 + resolution: "stacktrace-gps@npm:3.0.4" dependencies: source-map: "npm:0.5.6" stackframe: "npm:^1.1.1" From 6e8d154d4e9461635c1de7d31b769d611e3a5bff Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Tue, 27 Aug 2024 17:59:41 -0400 Subject: [PATCH 093/101] log fix --- package.json | 1 + public/app/fn_logger.ts | 80 +++------------------------------ scripts/webpack/webpack.prod.js | 1 + yarn.lock | 8 ++++ 4 files changed, 15 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index 257050cda428f..8f7a0c8da900c 100644 --- a/package.json +++ b/package.json @@ -336,6 +336,7 @@ "leven": "^4.0.0", "lodash": "4.17.21", "logfmt": "^1.3.2", + "loglevel": "^1.9.1", "lru-cache": "10.2.2", "lru-memoize": "^1.1.0", "lucene": "^2.1.1", diff --git a/public/app/fn_logger.ts b/public/app/fn_logger.ts index d1fd313d9b3e2..edc06d448d853 100644 --- a/public/app/fn_logger.ts +++ b/public/app/fn_logger.ts @@ -1,79 +1,9 @@ -import { isBoolean, noop } from 'lodash'; +import log from 'loglevel'; -const SHOULD_LOG = process.env.NODE_ENV !== 'production'; +const SHOULD_LOG = process.env.SHOULD_LOG === 'true'; -type Console = Pick; +const FnLoggerService = log.getLogger('[FN Grafana]'); -export class FnLoggerService { - private static readonly DEFAULT_SHOULD_LOG = false; +FnLoggerService.setLevel(SHOULD_LOG ? log.levels.DEBUG : log.levels.ERROR); - private static logger(shouldLog: boolean | null) { - /* eslint-disable-next-line */ - const flag = isBoolean(shouldLog) - ? shouldLog - : isBoolean(SHOULD_LOG) - ? SHOULD_LOG - : FnLoggerService.DEFAULT_SHOULD_LOG; - - if (flag) { - return console as Console; - } - - const noopConsole: Console = { - info: noop, - error: noop, - debug: noop, - warn: noop, - log: noop, - }; - - return noopConsole; - } - - /* eslint-disable @typescript-eslint/no-explicit-any */ - static debug = (shouldLog: boolean | null, ...args: any[]) => { - FnLoggerService.logger(shouldLog).debug(FnLoggerService.valuesToString(...args)); - }; - - static error = (shouldLog: boolean | null, ...args: any[]) => { - FnLoggerService.logger(shouldLog).error(FnLoggerService.valuesToString(...args)); - }; - - static warn = (shouldLog: boolean | null, ...args: any[]) => { - FnLoggerService.logger(shouldLog).warn(FnLoggerService.valuesToString(...args)); - }; - - static info = (shouldLog: boolean | null, ...args: any[]) => { - FnLoggerService.logger(shouldLog).info(FnLoggerService.valuesToString(...args)); - }; - - static log = (shouldLog: boolean | null, ...args: any[]) => { - FnLoggerService.logger(shouldLog).log(FnLoggerService.valuesToString(...args)); - }; - /* eslint-enable @typescript-eslint/no-explicit-any */ - - /* eslint-disable @typescript-eslint/no-explicit-any */ - private static readonly valuesToString = (...args: any[]): string => - args.map(FnLoggerService.valueToString).join(' '); - /* eslint-enable @typescript-eslint/no-explicit-any */ - - private static readonly valueToString = (value: V): string => { - if (typeof value === 'string') { - return value; - } - - if (Array.isArray(value)) { - return value.map(FnLoggerService.valueToString).join(' '); - } - - if (value instanceof Error) { - return value.message; - } - - try { - return JSON.stringify(value); - } catch { - return String(value); - } - }; -} +export { FnLoggerService }; diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 8db24b7a6bbc7..c160649a82a0e 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -97,6 +97,7 @@ module.exports = (env = {}) => new DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development'), + SHOULD_LOG: JSON.stringify('false'), }, }), new WebpackManifestPlugin({ diff --git a/yarn.lock b/yarn.lock index 38872ab3bb0fc..6fc858dc4301b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18640,6 +18640,7 @@ __metadata: leven: "npm:^4.0.0" lodash: "npm:4.17.21" logfmt: "npm:^1.3.2" + loglevel: "npm:^1.9.1" lru-cache: "npm:10.2.2" lru-memoize: "npm:^1.1.0" lucene: "npm:^2.1.1" @@ -22236,6 +22237,13 @@ __metadata: languageName: node linkType: hard +"loglevel@npm:^1.9.1": + version: 1.9.1 + resolution: "loglevel@npm:1.9.1" + checksum: 10/863cbbcddf850a937482c604e2d11586574a5110b746bb49c7cc04739e01f6035f6db841d25377106dd330bca7142d74995f15a97c5f3ea0af86d9472d4a99f4 + languageName: node + linkType: hard + "long@npm:^5.0.0": version: 5.2.3 resolution: "long@npm:5.2.3" From 8dbef0c593e8bc666a85f63b9ffbd6fa7369db88 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Thu, 29 Aug 2024 13:23:04 -0400 Subject: [PATCH 094/101] rebase issues resolved --- go.mod | 28 +- go.sum | 131 +++++- go.work.sum | 338 +++++++++++++- package.json | 6 +- .../src/dataframe/ArrayDataFrame.ts | 2 +- .../DateTimePickers/TimeRangePicker.tsx | 2 +- .../TimeRangePicker/TimePickerContent.tsx | 6 +- .../TimeRangePicker/TimePickerFooter.tsx | 3 +- .../TimeRangePicker/TimeRangeContent.tsx | 42 +- .../src/components/Dropdown/Dropdown.tsx | 9 +- .../grafana-ui/src/components/Icon/Icon.tsx | 42 +- .../src/components/Menu/MenuItem.tsx | 88 ++-- .../src/components/Menu/SubMenu.tsx | 80 ++-- .../grafana-ui/src/components/Table/Table.tsx | 2 +- .../ToolbarButton/ToolbarButton.tsx | 3 +- pkg/aggregator/go.mod | 85 ++-- pkg/aggregator/go.sum | 181 ++++--- pkg/api/dashboard.go | 106 +---- pkg/api/dtos/dashboard.go | 1 + pkg/api/plugin_resource_test.go | 14 +- pkg/apimachinery/go.mod | 16 +- pkg/apimachinery/go.sum | 32 +- pkg/apimachinery/identity/wrapper.go | 5 + pkg/apiserver/go.mod | 41 +- pkg/apiserver/go.sum | 108 ++--- pkg/build/go.mod | 41 +- pkg/build/go.sum | 80 ++-- pkg/build/wire/go.mod | 4 +- pkg/build/wire/go.sum | 8 +- .../backendplugin/coreplugin/registry.go | 3 + pkg/plugins/pfs/corelist/corelist_load_gen.go | 2 +- pkg/promlib/go.mod | 74 +-- pkg/promlib/go.sum | 158 ++++--- pkg/semconv/go.mod | 2 +- pkg/semconv/go.sum | 4 +- pkg/server/wire.go | 6 +- pkg/services/authn/clients/ext_jwt.go | 42 +- pkg/services/authn/identity.go | 5 +- pkg/services/authz/client.go | 5 +- pkg/services/contexthandler/contexthandler.go | 13 - pkg/services/featuremgmt/models.go | 2 + pkg/services/ldap/testing.go | 4 +- .../plugins_integration_test.go | 20 +- pkg/storage/unified/apistore/go.mod | 54 +-- pkg/storage/unified/apistore/go.sum | 132 +++--- pkg/storage/unified/resource/go.mod | 27 +- pkg/storage/unified/resource/go.sum | 76 +-- pkg/tsdb/cloudwatch/models/api.go | 12 - pkg/tsdb/cloudwatch/services/logs.go | 53 --- pkg/tsdb/cloudwatch/services/logs_test.go | 200 -------- pkg/tsdb/druid/druid.go | 6 +- pkg/util/xorm/go.mod | 2 +- pkg/util/xorm/go.sum | 8 +- .../app/core/components/Page/usePageTitle.ts | 18 +- .../TimePicker/TimePickerWithHistory.tsx | 2 +- public/app/core/reducers/fn-slice.ts | 4 +- public/app/features/alerting/unified/mocks.ts | 25 +- .../alerting/unified/state/actions.ts | 7 +- .../features/api-keys/ApiKeysPage.test.tsx | 2 +- .../sharing/ExportButton/ExportMenu.tsx | 26 +- .../dashboard/components/DashNav/DashNav.tsx | 54 +-- .../components/DashboardLoading/FnLoader.tsx | 2 +- .../DashboardRow/DashboardRow.test.tsx | 98 ---- .../components/DashboardRow/DashboardRow.tsx | 112 ++++- .../AnnotationsSettings.test.tsx | 2 +- .../DashboardSettings/LinksSettings.test.tsx | 2 - .../dashboard/components/SubMenu/SubMenu.tsx | 9 +- .../components/SubMenu/SubMenuItems.tsx | 3 +- .../dashboard/containers/DashboardPage.tsx | 10 +- .../dashboard/dashgrid/DashboardGrid.test.tsx | 6 +- .../dashboard/dashgrid/DashboardGrid.tsx | 6 - .../dashboard/dashgrid/DashboardPanel.tsx | 15 +- .../dashboard/dashgrid/LazyLoader.tsx | 2 +- .../dashgrid/PanelHeader/PanelHeader.tsx | 227 +++++---- .../dashboard/dashgrid/PanelStateWrapper.tsx | 122 ++--- .../features/dashboard/dashgrid/liveTimer.ts | 2 - .../dashboard/services/DashboardLoaderSrv.ts | 28 +- .../dashboard/state/initDashboard.test.ts | 4 +- .../features/dashboard/state/initDashboard.ts | 13 +- .../SpanFilters/SpanFilters.tsx | 2 +- .../app/features/org/OrgDetailsPage.test.tsx | 1 - .../app/features/plugins/built_in_plugins.ts | 183 ++++---- .../profile/UserProfileEditPage.test.tsx | 9 +- .../variables/pickers/PickerRenderer.tsx | 5 +- public/app/fn-app/create-mfe.ts | 19 +- public/app/fn-app/fn-app-provider.tsx | 7 +- .../fn-app/fn-dashboard-page/fn-dashboard.tsx | 2 +- .../fn-dashboard-page/render-fn-dashboard.tsx | 6 +- public/app/fn-app/types.ts | 3 +- public/app/fn-app/utils.tsx | 2 +- public/app/fn_app.ts | 101 ++-- public/app/fn_dashboard.ts | 6 +- .../plugins/datasource/cloudwatch/Search.tsx | 39 -- .../cloudwatch/components/Account.test.tsx | 1 - .../cloudwatch/components/Account.tsx | 2 +- .../cloudwatch/components/Search.test.tsx | 42 -- .../ConfigEditor.tsx | 20 - .../fifemon-graphql-datasource/DataSource.ts | 360 -------------- .../FN_DataSource.ts | 366 --------------- .../QueryEditor.tsx | 110 ----- .../VariableQueryEditor.tsx | 47 -- .../fifemon-graphql-datasource/module.ts | 13 - .../ConfigEditor.tsx | 8 +- .../DruidDataSource.ts | 74 +-- .../QueryEditor.tsx | 14 +- .../VariableQueryEditor.tsx | 12 +- .../builder/DruidQueryBuilder.tsx | 4 +- .../builder/abstract/Checkbox.tsx | 7 +- .../builder/abstract/Code.tsx | 7 +- .../builder/abstract/DateInterval.tsx | 37 +- .../builder/abstract/DateTime.tsx | 28 +- .../builder/abstract/Input.tsx | 5 +- .../builder/abstract/KeyValue.tsx | 5 +- .../builder/abstract/Multiple.tsx | 8 +- .../builder/abstract/Multiselect.tsx | 5 +- .../abstract/QueryBuilderComponent.tsx | 4 +- .../QueryBuilderComponentSelector.tsx | 17 +- .../builder/abstract/Row.tsx | 7 +- .../builder/abstract/Select.tsx | 5 +- .../builder/abstract/Table.tsx | 8 +- .../builder/abstract/types.ts | 1 + .../builder/aggregation/Aggregation.tsx | 3 +- .../builder/aggregation/Cardinality.tsx | 3 +- .../builder/aggregation/Count.tsx | 3 +- .../builder/aggregation/DoubleAny.tsx | 3 +- .../builder/aggregation/DoubleFirst.tsx | 3 +- .../builder/aggregation/DoubleLast.tsx | 3 +- .../builder/aggregation/DoubleMax.tsx | 3 +- .../builder/aggregation/DoubleMean.tsx | 3 +- .../builder/aggregation/DoubleMin.tsx | 3 +- .../builder/aggregation/DoubleSum.tsx | 3 +- .../builder/aggregation/Filtered.tsx | 6 +- .../builder/aggregation/FloatAny.tsx | 3 +- .../builder/aggregation/FloatFirst.tsx | 3 +- .../builder/aggregation/FloatLast.tsx | 3 +- .../builder/aggregation/FloatMax.tsx | 3 +- .../builder/aggregation/FloatMin.tsx | 3 +- .../builder/aggregation/FloatSum.tsx | 3 +- .../builder/aggregation/Histogram.tsx | 3 +- .../builder/aggregation/HyperUnique.tsx | 3 +- .../builder/aggregation/Javascript.tsx | 3 +- .../builder/aggregation/LongAny.tsx | 3 +- .../builder/aggregation/LongFirst.tsx | 3 +- .../builder/aggregation/LongLast.tsx | 3 +- .../builder/aggregation/LongMax.tsx | 3 +- .../builder/aggregation/LongMin.tsx | 3 +- .../builder/aggregation/LongSum.tsx | 3 +- .../aggregation/QuantilesDoublesSketch.tsx | 3 +- .../builder/aggregation/StringAny.tsx | 3 +- .../builder/aggregation/StringFirst.tsx | 3 +- .../aggregation/StringFirstFolding.tsx | 3 +- .../builder/aggregation/StringLast.tsx | 3 +- .../builder/aggregation/StringLastFolding.tsx | 3 +- .../builder/bound/Bound.tsx | 4 +- .../builder/bound/Polygon.tsx | 3 +- .../builder/bound/Radius.tsx | 3 +- .../builder/bound/Rectangular.tsx | 3 +- .../builder/datasource/DataSource.tsx | 4 +- .../builder/datasource/GlobalTable.tsx | 3 +- .../builder/datasource/Inline.tsx | 3 +- .../builder/datasource/Join.tsx | 4 +- .../builder/datasource/Lookup.tsx | 3 +- .../builder/datasource/Query.tsx | 3 +- .../builder/datasource/Table.tsx | 3 +- .../builder/datasource/Union.tsx | 3 +- .../builder/dimension/Default.tsx | 3 +- .../builder/dimension/Dimension.tsx | 4 +- .../builder/dimension/Extraction.tsx | 3 +- .../builder/dimension/ListFiltered.tsx | 4 +- .../builder/dimension/Lookup.tsx | 3 +- .../builder/dimension/PrefixFiltered.tsx | 3 +- .../builder/dimension/RegexFiltered.tsx | 3 +- .../builder/dimension/RegisteredLookup.tsx | 3 +- .../builder/extractionfn/Bucket.tsx | 3 +- .../builder/extractionfn/Cascade.tsx | 4 +- .../builder/extractionfn/ExtractionFn.tsx | 4 +- .../builder/extractionfn/Identity.tsx | 6 +- .../builder/extractionfn/Javascript.tsx | 3 +- .../builder/extractionfn/Lookup.tsx | 3 +- .../builder/extractionfn/Lower.tsx | 3 +- .../builder/extractionfn/Partial.tsx | 3 +- .../builder/extractionfn/Regex.tsx | 3 +- .../builder/extractionfn/RegisteredLookup.tsx | 3 +- .../builder/extractionfn/SearchQuery.tsx | 3 +- .../builder/extractionfn/StrLen.tsx | 6 +- .../builder/extractionfn/StringFormat.tsx | 3 +- .../builder/extractionfn/Substring.tsx | 3 +- .../builder/extractionfn/Time.tsx | 3 +- .../builder/extractionfn/TimeFormat.tsx | 3 +- .../builder/extractionfn/Upper.tsx | 3 +- .../builder/filter/And.tsx | 4 +- .../builder/filter/Bound.tsx | 4 +- .../builder/filter/ColumnComparison.tsx | 3 +- .../builder/filter/Expression.tsx | 4 +- .../builder/filter/Extraction.tsx | 6 +- .../builder/filter/False.tsx | 6 +- .../builder/filter/Filter.tsx | 4 +- .../builder/filter/FilterTuning.tsx | 4 +- .../builder/filter/In.tsx | 4 +- .../builder/filter/Interval.tsx | 6 +- .../builder/filter/Javascript.tsx | 4 +- .../builder/filter/Like.tsx | 4 +- .../builder/filter/Not.tsx | 4 +- .../builder/filter/Or.tsx | 4 +- .../builder/filter/Regex.tsx | 4 +- .../builder/filter/Search.tsx | 6 +- .../builder/filter/Selector.tsx | 4 +- .../builder/filter/Spatial.tsx | 6 +- .../builder/filter/True.tsx | 6 +- .../builder/granularity/Duration.tsx | 3 +- .../builder/granularity/Granularity.tsx | 4 +- .../builder/granularity/Period.tsx | 3 +- .../builder/granularity/Simple.tsx | 3 +- .../builder/havingspec/And.tsx | 4 +- .../builder/havingspec/DimSelector.tsx | 3 +- .../builder/havingspec/EqualTo.tsx | 3 +- .../builder/havingspec/Filter.tsx | 3 +- .../builder/havingspec/GreaterThan.tsx | 3 +- .../builder/havingspec/HavingSpec.tsx | 4 +- .../builder/havingspec/LessThan.tsx | 3 +- .../builder/havingspec/Not.tsx | 4 +- .../builder/havingspec/Or.tsx | 4 +- .../builder/limitspec/Default.tsx | 4 +- .../builder/limitspec/LimitSpec.tsx | 4 +- .../builder/limitspec/OrderByColumnSpecs.tsx | 3 +- .../builder/lookup/Lookup.tsx | 4 +- .../builder/lookup/Map.tsx | 3 +- .../builder/postaggregation/Arithmetic.tsx | 4 +- .../builder/postaggregation/Constant.tsx | 3 +- .../postaggregation/DoubleGreatest.tsx | 4 +- .../builder/postaggregation/DoubleLeast.tsx | 4 +- .../builder/postaggregation/FieldAccess.tsx | 3 +- .../postaggregation/FinalizingFieldAccess.tsx | 3 +- .../HyperUniqueCardinality.tsx | 3 +- .../builder/postaggregation/Javascript.tsx | 3 +- .../builder/postaggregation/LongGreatest.tsx | 4 +- .../builder/postaggregation/LongLeast.tsx | 4 +- .../postaggregation/PostAggregation.tsx | 4 +- .../QuantilesDoublesSketchToQuantile.tsx | 4 +- .../builder/query/DatasourceMetadata.tsx | 3 +- .../builder/query/GroupBy.tsx | 11 +- .../builder/query/Json.tsx | 3 +- .../builder/query/Query.tsx | 4 +- .../builder/query/Scan.tsx | 5 +- .../builder/query/Search.tsx | 7 +- .../builder/query/SegmentMetadata.tsx | 3 +- .../builder/query/Sql.tsx | 3 +- .../builder/query/TimeBoundary.tsx | 3 +- .../builder/query/Timeseries.tsx | 9 +- .../builder/query/TopN.tsx | 11 +- .../builder/querysegmentspec/Intervals.tsx | 3 +- .../querysegmentspec/QuerySegmentSpec.tsx | 4 +- .../builder/searchqueryspec/All.tsx | 6 +- .../builder/searchqueryspec/Contains.tsx | 3 +- .../builder/searchqueryspec/Fragment.tsx | 3 +- .../searchqueryspec/InsensitiveContains.tsx | 3 +- .../builder/searchqueryspec/Regex.tsx | 3 +- .../searchqueryspec/SearchQuerySpec.tsx | 4 +- .../builder/searchsortspec/AlphaNumeric.tsx | 3 +- .../builder/searchsortspec/Lexicographic.tsx | 3 +- .../builder/searchsortspec/Numeric.tsx | 3 +- .../builder/searchsortspec/SearchSortSpec.tsx | 4 +- .../builder/searchsortspec/StrLen.tsx | 3 +- .../builder/searchsortspec/Version.tsx | 3 +- .../builder/toinclude/All.tsx | 6 +- .../builder/toinclude/List.tsx | 3 +- .../builder/toinclude/None.tsx | 6 +- .../builder/toinclude/ToInclude.tsx | 4 +- .../builder/topnmetric/AlphaNumeric.tsx | 3 +- .../builder/topnmetric/Dimension.tsx | 3 +- .../builder/topnmetric/Inverted.tsx | 4 +- .../builder/topnmetric/Lexicographic.tsx | 3 +- .../builder/topnmetric/Numeric.tsx | 3 +- .../builder/topnmetric/TopNMetric.tsx | 4 +- .../builder/virtualcolumn/Expression.tsx | 3 +- .../builder/virtualcolumn/VirtualColumn.tsx | 4 +- .../ConnectionSettings/DruidAuthSettings.tsx | 5 +- .../DruidBasicAuthSettings.tsx | 4 +- .../DruidConnectionSettings.tsx | 4 +- .../ConnectionSettings/DruidHttpSettings.tsx | 3 +- .../DruidQueryContextSettings.tsx | 8 +- .../DruidQueryDefaultSettings.tsx | 8 +- .../QuerySettings/DruidQueryLogSettings.tsx | 8 +- .../DruidQueryRequestSettings.tsx | 6 +- .../DruidQueryResponseSettings.tsx | 8 +- .../QuerySettings/DruidQuerySettings.tsx | 8 +- .../grafadruid-druid-datasource/module.ts | 3 +- .../grafadruid-druid-datasource/types.ts | 3 +- public/app/plugins/panel/barchart/utils.ts | 5 +- .../app/plugins/panel/canvas/Connections.tsx | 241 ---------- public/app/store/configureStore.ts | 26 +- public/app/types/window.d.ts | 6 + public/microfrontends/fn_dashboard/index.html | 126 +---- public/views/error-template.html | 60 +++ public/views/error.html | 161 +++---- .../views/index-microfrontend-template.html | 16 +- public/views/index-template.html | 341 ++++++++++++++ public/views/index.html | 442 ++++++++++++++---- .../webpack/plugins/HTMLWebpackCSSChunks.js | 42 ++ scripts/webpack/webpack.dev.js | 66 +-- scripts/webpack/webpack.prod.js | 8 +- yarn.lock | 403 +++++++++++++++- 302 files changed, 3548 insertions(+), 3851 deletions(-) delete mode 100644 pkg/tsdb/cloudwatch/services/logs.go delete mode 100644 pkg/tsdb/cloudwatch/services/logs_test.go delete mode 100644 public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx delete mode 100644 public/app/plugins/datasource/cloudwatch/Search.tsx delete mode 100644 public/app/plugins/datasource/cloudwatch/components/Search.test.tsx delete mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/ConfigEditor.tsx delete mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/DataSource.ts delete mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts delete mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/QueryEditor.tsx delete mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/VariableQueryEditor.tsx delete mode 100644 public/app/plugins/datasource/fifemon-graphql-datasource/module.ts delete mode 100644 public/app/plugins/panel/canvas/Connections.tsx create mode 100644 public/views/error-template.html create mode 100644 public/views/index-template.html create mode 100644 scripts/webpack/plugins/HTMLWebpackCSSChunks.js diff --git a/go.mod b/go.mod index 3e5f9a1b72aaa..d7fccf67113ac 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/fatih/color v1.16.0 // @grafana/grafana-backend-group github.com/fullstorydev/grpchan v1.1.1 // @grafana/grafana-backend-group github.com/gchaincl/sqlhooks v1.3.0 // @grafana/grafana-search-and-storage - github.com/getkin/kin-openapi v0.125.0 // @grafana/grafana-as-code + github.com/getkin/kin-openapi v0.127.0 // @grafana/grafana-as-code github.com/go-jose/go-jose/v3 v3.0.3 // @grafana/identity-access-team github.com/go-kit/log v0.2.1 // @grafana/grafana-backend-group github.com/go-ldap/ldap/v3 v3.4.4 // @grafana/identity-access-team @@ -75,8 +75,6 @@ require ( github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group github.com/gorilla/websocket v1.5.0 // @grafana/grafana-app-platform-squad github.com/grafana/alerting v0.0.0-20240822131459-9daa6239cc41 // @grafana/alerting-backend - github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db // @grafana/identity-access-team - github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db // @grafana/identity-access-team github.com/grafana/codejen v0.0.3 // @grafana/dataviz-squad github.com/grafana/cuetsy v0.1.11 // @grafana/grafana-as-code github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics @@ -130,7 +128,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // @grafana/alerting-backend github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // @grafana/alerting-backend github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // @grafana/grafana-operator-experience-squad - github.com/oapi-codegen/oapi-codegen/v2 v2.3.0 // @grafana/grafana-as-code + github.com/oapi-codegen/oapi-codegen/v2 v2.3.1-0.20240823215434-d232e9efa9f5 // @grafana/grafana-as-code github.com/oklog/ulid/v2 v2.1.0 // @grafana/identity-access-team github.com/olekukonko/tablewriter v0.0.5 // @grafana/grafana-backend-group github.com/openfga/api/proto v0.0.0-20240529184453-5b0b4941f3e0 // @grafana/identity-access-team @@ -425,7 +423,6 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect - github.com/yudai/pp v2.0.1+incompatible // indirect github.com/yuin/gopher-lua v1.1.1 // indirect github.com/zclconf/go-cty v1.13.0 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect @@ -477,12 +474,30 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect ) +require ( + github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible + github.com/bitly/go-simplejson v0.5.1 + github.com/grafadruid/go-druid v0.0.7-0.20230607082331-983aa577d90a + github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 + github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd + github.com/grafana/thema v0.0.0-20240605110052-2016107581da +) + require ( cloud.google.com/go/longrunning v0.5.12 // indirect github.com/at-wat/mqtt-go v0.19.4 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect + github.com/getsentry/sentry-go v0.12.0 // indirect github.com/grafana/grafana/pkg/semconv v0.0.0-20240808213237-f4d2e064f435 // indirect github.com/hairyhenderson/go-which v0.2.0 // indirect github.com/iancoleman/orderedmap v0.3.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/speakeasy-api/openapi-overlay v0.9.0 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect ) // Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream @@ -499,8 +514,7 @@ replace xorm.io/xorm => github.com/grafana/grafana/pkg/util/xorm v0.0.1 // lock for mysql tsdb compat replace github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.7.1 -replace google.golang.org/genproto => google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 // This is for sending custom HTTP headers in druid client. // Change in upstream: https://github.com/grafadruid/go-druid/pull/71 -replace github.com/grafadruid/go-druid => github.com/fluxninja/go-druid v0.0.0-20220825112309-14a37dd3317d +// replace github.com/grafadruid/go-druid => github.com/fluxninja/go-druid v0.0.0-20220825112309-14a37dd3317d diff --git a/go.sum b/go.sum index 41c1fe8452ba4..383cfdd9912dc 100644 --- a/go.sum +++ b/go.sum @@ -1341,6 +1341,7 @@ filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg= filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= @@ -1423,6 +1424,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/Code-Hex/go-generics-cache v1.5.1 h1:6vhZGc5M7Y/YD8cIUcY8kcuQLB4cHR7U+0KMqAA0KcU= github.com/Code-Hex/go-generics-cache v1.5.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= @@ -1435,7 +1438,9 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/KimMachineGun/automemlimit v0.6.0/go.mod h1:T7xYht7B8r6AG/AqFcUdc7fzd2bIdBKmepfP2S1svPY= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= @@ -1467,6 +1472,7 @@ github.com/RoaringBitmap/real-roaring-datasets v0.0.0-20190726190000-eb7c87156f7 github.com/RoaringBitmap/roaring v0.9.1/go.mod h1:h1B7iIUOmnAeb5ytYMvnHJwxMc6LUrwBnzXWRuqTQUc= github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo= github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -1475,6 +1481,7 @@ github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3H 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= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -1597,6 +1604,7 @@ github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f h1:y06x6vGnFYfXUoVMbrcP1Uzpj4JG01eB5vRps9G8agM= github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f/go.mod h1:2stgcRjl6QmW+gU2h5E7BQXg4HU0gzxKWDuT5HviN9s= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= @@ -1640,7 +1648,6 @@ github.com/blugelabs/ice v0.2.0/go.mod h1:7foiDf4V83FIYYnGh2LOoRWsbNoCqAAMNgKn87 github.com/blugelabs/ice v1.0.0 h1:um7wf9e6jbkTVCrOyQq3tKK43fBMOvLUYxbj3Qtc4eo= github.com/blugelabs/ice v1.0.0/go.mod h1:gNfFPk5zM+yxJROhthxhVQYjpBO9amuxWXJQ2Lo+IbQ= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= @@ -1731,7 +1738,15 @@ github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b80 github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/containerd/cgroups/v3 v3.0.1/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw= github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -1787,7 +1802,9 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= 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-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= @@ -1816,6 +1833,9 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -1829,6 +1849,7 @@ github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/efficientgo/tools/core v0.0.0-20220225185207-fe763185946b h1:ZHiD4/yE4idlbqvAO6iYCOYRzOMRpxkW+FKasRA3tsQ= github.com/efficientgo/tools/core v0.0.0-20220225185207-fe763185946b/go.mod h1:OmVcnJopJL8d3X3sSXTiypGoUSgFq1aDGmlrdi9dn/M= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M= github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= @@ -1864,10 +1885,12 @@ github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87K github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= @@ -1877,6 +1900,7 @@ github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8Wlg github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 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= @@ -1901,13 +1925,21 @@ github.com/fullstorydev/grpchan v1.1.1 h1:heQqIJlAv5Cnks9a70GRL2EJke6QQoUB25VGR6 github.com/fullstorydev/grpchan v1.1.1/go.mod h1:f4HpiV8V6htfY/K44GWV1ESQzHBTq7DinhzqQ95lpgc= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gchaincl/sqlhooks v1.3.0 h1:yKPXxW9a5CjXaVf2HkQn6wn7TZARvbAOAelr3H8vK2Y= github.com/gchaincl/sqlhooks v1.3.0/go.mod h1:9BypXnereMT0+Ys8WGWHqzgkkOfHIhyeUCqXC24ra34= -github.com/getkin/kin-openapi v0.125.0 h1:jyQCyf2qXS1qvs2U00xQzkGCqYPhEhZDmSmVt65fXno= -github.com/getkin/kin-openapi v0.125.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= +github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= +github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= @@ -1950,6 +1982,7 @@ 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.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/analysis v0.21.5/go.mod h1:25YcZosX9Lwz2wBsrFrrsL8bmjjXdlyP6zsr2AMy29M= @@ -2022,8 +2055,11 @@ github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= @@ -2044,9 +2080,11 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -2111,6 +2149,7 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= @@ -2246,15 +2285,18 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafadruid/go-druid v0.0.7-0.20230607082331-983aa577d90a h1:+2Q5MlRJc7nxT5H4aPzWK9YyC6uO3bhiw2yElOz4Nfo= +github.com/grafadruid/go-druid v0.0.7-0.20230607082331-983aa577d90a/go.mod h1:KY3a6MrVMKkXgMTwBS9Nrhm1E8OWyR4gd0WzUi8d/zM= github.com/grafana/alerting v0.0.0-20240822131459-9daa6239cc41 h1:p+UsX43BoDH5YlG6xUd9xDS3M4sWouy8VJ+ODv5S6uE= github.com/grafana/alerting v0.0.0-20240822131459-9daa6239cc41/go.mod h1:GMLi6d09Xqo96fCVUjNk//rcjP5NKEdjOzfWIffD5r4= -github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db h1:z++X4DdoX+aNlZNT1ZY4cykiFay4+f077pa0AG48SGg= -github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db/go.mod h1:ptt910z9KFfpVSIbSbXvTRR7tS19mxD7EtmVbbJi/WE= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= +github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 h1:SU+p1ck8037cz6F8W38PIL9MzRb6YMeNqc7+GHDuqiU= +github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2/go.mod h1:PFzXbCrn0GIpN4KwT6NP1l5Z1CPLfmKHnYx8rZzQcyY= +github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd h1:sIlR7n38/MnZvX2qxDEszywXdI5soCwQ78aTDSARvus= +github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= 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= @@ -2319,6 +2361,8 @@ github.com/grafana/sqlds/v3 v3.2.0 h1:WXuYEaFfiCvgm8kK2ixx44/zAEjFzCylA2+RF3GBqZ github.com/grafana/sqlds/v3 v3.2.0/go.mod h1:kH0WuHUR3j0Q7IEymbm2JiaPckUhRCbqjV9ajaBAnmM= github.com/grafana/tempo v1.5.1-0.20240604192202-01f4bc8ac2d1 h1:cSE1u4IUQ9EPcQErMZ9YVYayJTIGgH4g2E1Rp2WmGy0= github.com/grafana/tempo v1.5.1-0.20240604192202-01f4bc8ac2d1/go.mod h1:ttAEYdYVYBNngPulKIHkmHvjXfLfX7jDWI74jzb8jh4= +github.com/grafana/thema v0.0.0-20240605110052-2016107581da h1:QhkXTxftS9baiXXweuMO6+MN4cIDrQxQpT1gEVuIpMk= +github.com/grafana/thema v0.0.0-20240605110052-2016107581da/go.mod h1:AOyC9mxvuzfiGf4GgVu0dLpPlRl8clSnhRNUpOK0NAA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= @@ -2382,6 +2426,7 @@ github.com/hashicorp/go-plugin v1.2.2/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYt github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= @@ -2447,6 +2492,7 @@ github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4 github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= @@ -2461,6 +2507,7 @@ github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -2477,6 +2524,11 @@ github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/ionos-cloud/sdk-go/v6 v6.1.11 h1:J/uRN4UWO3wCyGOeDdMKv8LWRzKu6UIkLEaes38Kzh8= github.com/ionos-cloud/sdk-go/v6 v6.1.11/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= @@ -2549,9 +2601,15 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/karlseguin/ccache/v3 v3.0.5 h1:hFX25+fxzNjsRlREYsoGNa2LoVEw5mPF8wkWq/UnevQ= github.com/karlseguin/ccache/v3 v3.0.5/go.mod h1:qxC372+Qn+IBj8Pe3KvGjHPj0sWwEF7AeZVhsNPZ6uY= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -2559,6 +2617,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= @@ -2566,6 +2626,7 @@ github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -2591,6 +2652,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= @@ -2636,10 +2699,12 @@ github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxq github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM= github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -2648,7 +2713,9 @@ github.com/mattn/go-ieproxy v0.0.11 h1:MQ/5BuGSgDAHZOJe6YY80IF2UVCfGkwfo6AeD7HtH github.com/mattn/go-ieproxy v0.0.11/go.mod h1:/NsJd+kxZBmjMc5hrJCKMbP57B84rvq9BiDRbtO9AS0= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -2669,13 +2736,16 @@ github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= 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/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/microsoft/go-mssqldb v1.7.0 h1:sgMPW0HA6Ihd37Yx0MzHyKD726C2kY/8KJsQtXHNaAs= github.com/microsoft/go-mssqldb v1.7.0/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -2766,6 +2836,7 @@ github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto= github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= @@ -2801,8 +2872,8 @@ github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oapi-codegen/oapi-codegen/v2 v2.3.0 h1:rICjNsHbPP1LttefanBPnwsSwl09SqhCO7Ee623qR84= -github.com/oapi-codegen/oapi-codegen/v2 v2.3.0/go.mod h1:4k+cJeSq5ntkwlcpQSxLxICCxQzCL772o30PxdibRt4= +github.com/oapi-codegen/oapi-codegen/v2 v2.3.1-0.20240823215434-d232e9efa9f5 h1:v1Go6tsT4lfcVzlSXjg6CfSGGgG8kWXPHOthLkx8eV8= +github.com/oapi-codegen/oapi-codegen/v2 v2.3.1-0.20240823215434-d232e9efa9f5/go.mod h1:ZBPUgGu64Z0KswMMFH+qiCjpZmnyXB0khpUR/z79tmg= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -2818,6 +2889,8 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 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= @@ -2841,6 +2914,7 @@ github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xl github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= @@ -2923,6 +2997,8 @@ github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFu github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -3038,6 +3114,7 @@ github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYe github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= @@ -3067,6 +3144,7 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26 h1:F+GIVtGqCFxPxO46ujf8cEOP574MBoRm3gNbPXECbxs= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scottlepp/go-duck v0.1.0 h1:Lfunl1wd767v0dF0/dr+mBh+KnUFuDmgNycC76NJjeE= github.com/scottlepp/go-duck v0.1.0/go.mod h1:xGoYUbgph5AbxwsMElWv2i/mgzQl89WIgwE69Ytml7Q= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -3076,6 +3154,8 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/segmentio/encoding v0.3.6 h1:E6lVLyDPseWEulBmCmAKPanDd3jiyGDo5gMcugCRwZQ= github.com/segmentio/encoding v0.3.6/go.mod h1:n0JeuIqEQrQoPDGsjo8UNd1iA0U8d8+oHAA4E3G3OxM= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= @@ -3116,6 +3196,8 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/speakeasy-api/openapi-overlay v0.9.0 h1:Wrz6NO02cNlLzx1fB093lBlYxSI54VRhy1aSutx0PQg= +github.com/speakeasy-api/openapi-overlay v0.9.0/go.mod h1:f5FloQrHA7MsxYg9djzMD5h6dxrHjVVByWKh7an8TRc= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= @@ -3206,7 +3288,11 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 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.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 h1:aVGB3YnaS/JNfOW3tiHIlmNmTDg618va+eT0mVomgyI= @@ -3222,9 +3308,16 @@ github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vburenin/ifacemaker v1.2.1/go.mod h1:5WqrzX2aD7/hi+okBjcaEQJMg4lDGrpuEX3B8L4Wgrs= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/wk8/go-ordered-map v1.0.0 h1:BV7z+2PaK8LTSd/mWgY12HyMAo5CEgkHqbkVq2thqr8= @@ -3239,6 +3332,9 @@ github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3k github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= @@ -3248,6 +3344,7 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= @@ -3432,6 +3529,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -3439,6 +3537,7 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -3562,6 +3661,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -3572,6 +3672,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -3608,6 +3709,7 @@ golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -3740,6 +3842,7 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -3806,6 +3909,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -3912,6 +4016,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -3923,12 +4028,14 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -4487,13 +4594,17 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -4511,6 +4622,8 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.work.sum b/go.work.sum index 03dfc6d544274..5d638e1284a5d 100644 --- a/go.work.sum +++ b/go.work.sum @@ -6,40 +6,62 @@ cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbD cloud.google.com/go/accessapproval v1.7.5 h1:uzmAMSgYcnlHa9X9YSQZ4Q1wlfl4NNkZyQgho1Z6p04= cloud.google.com/go/accessapproval v1.7.11 h1:MgtE8CI+YJWPGGHnxQ9z1VQqV87h+vSGy2MeM/m0ggQ= cloud.google.com/go/accessapproval v1.7.11/go.mod h1:KGK3+CLDWm4BvjN0wFtZqdFUGhxlTvTF6PhAwQJGL4M= +cloud.google.com/go/accessapproval v1.7.12 h1:uxJBvDCor5iuCYOVby/0WTsHSMyBh8bpJ6hzqKdcL64= +cloud.google.com/go/accessapproval v1.7.12/go.mod h1:wvyt8Okohbq1i8/aPbCMBNwGQFZaNli5d+1qa/5zgGo= cloud.google.com/go/accesscontextmanager v1.8.5 h1:2GLNaNu9KRJhJBFTIVRoPwk6xE5mUDgD47abBq4Zp/I= cloud.google.com/go/accesscontextmanager v1.8.11 h1:IQ3KLJmNKPgstN0ZcRw0niU4KfsiOZmzvcGCF+NT618= cloud.google.com/go/accesscontextmanager v1.8.11/go.mod h1:nwPysISS3KR5qXipAU6cW/UbDavDdTBBgPohbkhGSok= +cloud.google.com/go/accesscontextmanager v1.8.12 h1:u3gLVJFZ8couGeVBZmhK0ON5YU3w9YIXOVr+THOik/M= +cloud.google.com/go/accesscontextmanager v1.8.12/go.mod h1:EmaVYmffq+2jA2waP0/XHECDkaOKVztxVsdzl65t8hw= cloud.google.com/go/aiplatform v1.60.0 h1:0cSrii1ZeLr16MbBoocyy5KVnrSdiQ3KN/vtrTe7RqE= cloud.google.com/go/aiplatform v1.68.0 h1:EPPqgHDJpBZKRvv+OsB3cr0jYz3EL2pZ+802rBPcG8U= cloud.google.com/go/aiplatform v1.68.0/go.mod h1:105MFA3svHjC3Oazl7yjXAmIR89LKhRAeNdnDKJczME= cloud.google.com/go/analytics v0.23.0 h1:Q+y94XH84jM8SK8O7qiY/PJRexb6n7dRbQ6PiUa4YGM= cloud.google.com/go/analytics v0.23.6 h1:BY8ZY7hQwKBi+lNp1IkiMTOK4xe4lxZCeYv3S9ARXtE= cloud.google.com/go/analytics v0.23.6/go.mod h1:cFz5GwWHrWQi8OHKP9ep3Z4pvHgGcG9lPnFQ+8kXsNo= +cloud.google.com/go/analytics v0.24.0 h1:wIMRXRQAanMWaUGSOglVwEmpZqCC4WAs9YacMuGcD88= +cloud.google.com/go/analytics v0.24.0/go.mod h1:NpavJSb6TSO56hGpX1+4JL7js6AkKl27TEqzW9Sn7E4= cloud.google.com/go/apigateway v1.6.5 h1:sPXnpk+6TneKIrjCjcpX5YGsAKy3PTdpIchoj8/74OE= cloud.google.com/go/apigateway v1.6.11 h1:VtEvpnqqY2T5gZBzo+p7C87yGH3omHUkPIbRQkmGS9I= cloud.google.com/go/apigateway v1.6.11/go.mod h1:4KsrYHn/kSWx8SNUgizvaz+lBZ4uZfU7mUDsGhmkWfM= +cloud.google.com/go/apigateway v1.6.12 h1:yynQNoSDVxbc8iPA2kLC4RWj1Ir64/FhGcXbyhJKC4c= +cloud.google.com/go/apigateway v1.6.12/go.mod h1:2RX6Op78cxqMtENfJW8kKpwtBCFVJGyvBtSR9l6v7aM= cloud.google.com/go/apigeeconnect v1.6.5 h1:CrfIKv9Go3fh/QfQgisU3MeP90Ww7l/sVGmr3TpECo8= cloud.google.com/go/apigeeconnect v1.6.11 h1:CftZgGXFRLJeD2/5ZIdWuAMxW/88UG9tHhRPI/NY75M= cloud.google.com/go/apigeeconnect v1.6.11/go.mod h1:iMQLTeKxtKL+sb0D+pFlS/TO6za2IUOh/cwMEtn/4g0= +cloud.google.com/go/apigeeconnect v1.6.12 h1:Pq2wTmm41l2w5sLuxEGRZmXhYULKg5qIWcvGEOsFhZQ= +cloud.google.com/go/apigeeconnect v1.6.12/go.mod h1:/DSr1IlfzrXeKjS6c3+8P04avr+4U5S7J3F69SNGFkY= cloud.google.com/go/apigeeregistry v0.8.3 h1:C+QU2K+DzDjk4g074ouwHQGkoff1h5OMQp6sblCVreQ= cloud.google.com/go/apigeeregistry v0.8.9 h1:3vLwk0tS9L++6ZyV4RDH4UCydfVoqxJbpWvqG6MTtUw= cloud.google.com/go/apigeeregistry v0.8.9/go.mod h1:4XivwtSdfSO16XZdMEQDBCMCWDp3jkCBRhVgamQfLSA= +cloud.google.com/go/apigeeregistry v0.8.10 h1:DYqJWmGXIfPWnvSER1eIrMvCpzpPaWyfwUbZ9n51tR0= +cloud.google.com/go/apigeeregistry v0.8.10/go.mod h1:3uJa4XfNqvhIvKksKEE7UahxZY1/2Uj07cCfT/RJZZM= cloud.google.com/go/apikeys v0.6.0 h1:B9CdHFZTFjVti89tmyXXrO+7vSNo2jvZuHG8zD5trdQ= cloud.google.com/go/appengine v1.8.5 h1:l2SviT44zWQiOv8bPoMBzW0vOcMO22iO0s+nVtVhdts= cloud.google.com/go/appengine v1.8.11 h1:ZLoWWwakgRzRnXX2bsgk2g1sdzti3wq+ebunTJsZNog= cloud.google.com/go/appengine v1.8.11/go.mod h1:xET3coaDUj+OP4TgnZlgQ+rG2R9fG2nblya13czP56Q= +cloud.google.com/go/appengine v1.8.12 h1:R4n+yN8pyOZQmufa5NlvPKLnG4C0YIAgYUmKLHN7Xgg= +cloud.google.com/go/appengine v1.8.12/go.mod h1:31Ib+S1sYnRQmCtfGqEf6EfzsiYy98EuDtLlvmpmx6U= cloud.google.com/go/area120 v0.8.5 h1:vTs08KPLN/iMzTbxpu5ciL06KcsrVPMjz4IwcQyZ4uY= cloud.google.com/go/area120 v0.8.11 h1:UID1dl7lW2zs8OpYVtVZ5WsXU9kUcxC1nd3nnToHW70= cloud.google.com/go/area120 v0.8.11/go.mod h1:VBxJejRAJqeuzXQBbh5iHBYUkIjZk5UzFZLCXmzap2o= +cloud.google.com/go/area120 v0.8.12 h1:MIAp/4z3v6RVmdhBy20xL3q2eFCpMRSk9gQqxwppu44= +cloud.google.com/go/area120 v0.8.12/go.mod h1:W94qTbrwhzGimOeoClrGdm5DAkMGlg/V6Maldra5QM8= cloud.google.com/go/artifactregistry v1.14.7 h1:W9sVlyb1VRcUf83w7aM3yMsnp4HS4PoyGqYQNG0O5lI= cloud.google.com/go/artifactregistry v1.14.13 h1:NNK4vYVA5NGQmbmYidfJhnfmYU6SSSRUM2oopNouJNs= cloud.google.com/go/artifactregistry v1.14.13/go.mod h1:zQ/T4xoAFPtcxshl+Q4TJBgsy7APYR/BLd2z3xEAqRA= +cloud.google.com/go/artifactregistry v1.14.14 h1:RADsnxebM3WPtZrvWx2PYGWWxyqEsbe3rTTDRad6cZM= +cloud.google.com/go/artifactregistry v1.14.14/go.mod h1:lPHksFcKpcZRrhGNx87a6SSygv0hfWi6Cd0gnWIUU4U= cloud.google.com/go/asset v1.17.2 h1:xgFnBP3luSbUcC9RWJvb3Zkt+y/wW6PKwPHr3ssnIP8= cloud.google.com/go/asset v1.19.5 h1:/R2XZS6lR8oj/Y3L+epD2yy7mf44Zp62H4xZ4vzaR/Y= cloud.google.com/go/asset v1.19.5/go.mod h1:sqyLOYaLLfc4ACcn3YxqHno+J7lRt9NJTdO50zCUcY0= +cloud.google.com/go/asset v1.19.6 h1:p8Huo2TW4GyTfqQZuvUsmvYc3bXC1uS51VvpKfPfqqU= +cloud.google.com/go/asset v1.19.6/go.mod h1:UsijVGuWC6uml/+ODlL+mv6e3dZ52fbdOfOkiv4f0cE= cloud.google.com/go/assuredworkloads v1.11.5 h1:gCrN3IyvqY3cP0wh2h43d99CgH3G+WYs9CeuFVKChR8= cloud.google.com/go/assuredworkloads v1.11.11 h1:pwZp9o8aF5QmX4Z0YNlRe1ZOUzDw0UALmkem3aPobZc= cloud.google.com/go/assuredworkloads v1.11.11/go.mod h1:vaYs6+MHqJvLKYgZBOsuuOhBgNNIguhRU0Kt7JTGcnI= +cloud.google.com/go/assuredworkloads v1.11.12 h1:Oh8gYugn66aqjxlCEJq7WMEo7W8RR12mPK0B2FFfhL4= +cloud.google.com/go/assuredworkloads v1.11.12/go.mod h1:yYnk9icCH5XEkqjJinBNBDv5mSvi1FYhpA9Q+BpTwew= cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w= cloud.google.com/go/auth v0.5.1/go.mod h1:vbZT8GjzDf3AVqCcQmqeeM32U9HBFc32vVVAbwDsa6s= cloud.google.com/go/auth v0.6.1/go.mod h1:eFHG7zDzbXHKmjJddFG/rBlcGp6t25SwRUiEQSlO4x4= @@ -51,158 +73,252 @@ cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX cloud.google.com/go/automl v1.13.5 h1:ijiJy9sYWh75WrqImXsfWc1e3HR3iO+ef9fvW03Ig/4= cloud.google.com/go/automl v1.13.11 h1:FBCLjGS+Did/wtRHqyS055bRs/EJXx3meTvHPcdZgk8= cloud.google.com/go/automl v1.13.11/go.mod h1:oMJdXRDOVC+Eq3PnGhhxSut5Hm9TSyVx1aLEOgerOw8= +cloud.google.com/go/automl v1.13.12 h1:sjA6i5RbSqtgVzlLStZN3++AHKbZaCCvBmt68NeAAS0= +cloud.google.com/go/automl v1.13.12/go.mod h1:Rw8hmEIlKyvdhbFXjLrLvM2qNKZNwf5oraS5DervadE= cloud.google.com/go/baremetalsolution v1.2.4 h1:LFydisRmS7hQk9P/YhekwuZGqb45TW4QavcrMToWo5A= cloud.google.com/go/baremetalsolution v1.2.10 h1:VvBiXT9QJ4VpNVyfzHhLScY1aymZxpQgOa20yUvgphw= cloud.google.com/go/baremetalsolution v1.2.10/go.mod h1:eO2c2NMRy5ytcNPhG78KPsWGNsX5W/tUsCOWmYihx6I= +cloud.google.com/go/baremetalsolution v1.2.11 h1:rhMIixzQvm9cy8Ks3etB/JQOMw5vU8z71Jqf7VwI1Ts= +cloud.google.com/go/baremetalsolution v1.2.11/go.mod h1:bqthxNtU+n3gwWxoyXVR9VdSqIfVcgmpYtBlXQkeWq8= cloud.google.com/go/batch v1.8.0 h1:2HK4JerwVaIcCh/lJiHwh6+uswPthiMMWhiSWLELayk= cloud.google.com/go/batch v1.9.2 h1:o1RAjc0ExGAAm41YB9LbJZyJDgZR4M6SKyITsd/Smr4= cloud.google.com/go/batch v1.9.2/go.mod h1:smqwS4sleDJVAEzBt/TzFfXLktmWjFNugGDWl8coKX4= +cloud.google.com/go/batch v1.9.4 h1:JQWzsdmjnONvqNWeAubtDI6OIFv/v2lCYGzx8lpxTKg= +cloud.google.com/go/batch v1.9.4/go.mod h1:qqfXThFPI9dyDK1PfidiEOM/MrS+jUQualcQJytJCLA= cloud.google.com/go/beyondcorp v1.0.4 h1:qs0J0O9Ol2h1yA0AU+r7l3hOCPzs2MjE1d6d/kaHIKo= cloud.google.com/go/beyondcorp v1.0.10 h1:K4blSIQZn3YO4F4LmvWrH52pb8Y0L3NOrwkf22+x67M= cloud.google.com/go/beyondcorp v1.0.10/go.mod h1:G09WxvxJASbxbrzaJUMVvNsB1ZiaKxpbtkjiFtpDtbo= +cloud.google.com/go/beyondcorp v1.0.11 h1:oBXJtKP2J7VLqYQf6l5i2Cqm/qjFJPngnGKbzehkxYU= +cloud.google.com/go/beyondcorp v1.0.11/go.mod h1:V0EIXuYoyqKkHfnNCYZrNv6M+WYWJGIr5h019LurF3I= cloud.google.com/go/bigquery v1.59.1 h1:CpT+/njKuKT3CEmswm6IbhNu9u35zt5dO4yPDLW+nG4= cloud.google.com/go/bigquery v1.62.0 h1:SYEA2f7fKqbSRRBHb7g0iHTtZvtPSPYdXfmqsjpsBwo= cloud.google.com/go/bigquery v1.62.0/go.mod h1:5ee+ZkF1x/ntgCsFQJAQTM3QkAZOecfCmvxhkJsWRSA= cloud.google.com/go/bigtable v1.27.2-0.20240802230159-f371928b558f h1:UR2/6M/bSN8PPQlhaq+57w21VZLcEvq4ujsHd1p/G2s= cloud.google.com/go/bigtable v1.27.2-0.20240802230159-f371928b558f/go.mod h1:avmXcmxVbLJAo9moICRYMgDyTTPoV0MA0lHKnyqV4fQ= +cloud.google.com/go/bigtable v1.29.0 h1:2CnFjKPwjpZMZdTi2RpppvxzD80zKzDYrLYEQw/NnAs= +cloud.google.com/go/bigtable v1.29.0/go.mod h1:5p909nNdWaNUcWs6KGZO8mI5HUovstlmrIi7+eA5PTQ= cloud.google.com/go/billing v1.18.2 h1:oWUEQvuC4JvtnqLZ35zgzdbuHt4Itbftvzbe6aEyFdE= cloud.google.com/go/billing v1.18.9 h1:sGRWx7PvsfHuZyx151Xr6CrORIgjvCMO4GRabihSdQQ= cloud.google.com/go/billing v1.18.9/go.mod h1:bKTnh8MBfCMUT1fzZ936CPN9rZG7ZEiHB2J3SjIjByc= +cloud.google.com/go/billing v1.18.10 h1:Hguzxohg+0U/qMFmB0hyK/rM1yH1VSARMgZ8fM1K5as= +cloud.google.com/go/billing v1.18.10/go.mod h1:Lt+Qrjqsde38l/h1+9fzu44Pv9t+Suyf/p973mrg+xU= cloud.google.com/go/binaryauthorization v1.8.1 h1:1jcyh2uIUwSZkJ/JmL8kd5SUkL/Krbv8zmYLEbAz6kY= cloud.google.com/go/binaryauthorization v1.8.7 h1:ItT9uR/0/ok2Ru3LCcbSIBUPsKqTA49ZmxCupqQaeFo= cloud.google.com/go/binaryauthorization v1.8.7/go.mod h1:cRj4teQhOme5SbWQa96vTDATQdMftdT5324BznxANtg= +cloud.google.com/go/binaryauthorization v1.8.8 h1:Gxcy5/ydfTg2CviIxnZPVCNcFoDmQRbjzfAKg8bDJAU= +cloud.google.com/go/binaryauthorization v1.8.8/go.mod h1:D7B3gkNPdZ1Zj2IEyfypDTgbwFgTWE2SE6Csz0f46jg= cloud.google.com/go/certificatemanager v1.7.5 h1:UMBr/twXvH3jcT5J5/YjRxf2tvwTYIfrpemTebe0txc= cloud.google.com/go/certificatemanager v1.8.5 h1:ASC9N81NU8JnGzi9kiY2QTqtTgOziwGv48sjt3YG420= cloud.google.com/go/certificatemanager v1.8.5/go.mod h1:r2xINtJ/4xSz85VsqvjY53qdlrdCjyniib9Jp98ZKKM= +cloud.google.com/go/certificatemanager v1.8.6 h1:ekHCSJWJ8NFWvCRLRRWrJh1iPeJAKx0oIq0i9gFyVRM= +cloud.google.com/go/certificatemanager v1.8.6/go.mod h1:ZsK7vU+XFDfSRwOqB4GjAGzawIIA3dWPXaFC9I5Jsts= cloud.google.com/go/channel v1.17.5 h1:/omiBnyFjm4S1ETHoOmJbL7LH7Ljcei4rYG6Sj3hc80= cloud.google.com/go/channel v1.17.11 h1:AkKyMl2pSoJxBQtjAd6LYOtMgOaCl/kuiKoSg/Gf/H4= cloud.google.com/go/channel v1.17.11/go.mod h1:gjWCDBcTGQce/BSMoe2lAqhlq0dIRiZuktvBKXUawp0= +cloud.google.com/go/channel v1.17.12 h1:JNtAUfwGEOgeBp1bOxSzY/Hi3H1ARySNrj5cNBmOG+M= +cloud.google.com/go/channel v1.17.12/go.mod h1:DoVQacEH1YuNqIZVN8v67cXGxaUyOgjrst+/+pkVqWU= cloud.google.com/go/cloudbuild v1.15.1 h1:ZB6oOmJo+MTov9n629fiCrO9YZPOg25FZvQ7gIHu5ng= cloud.google.com/go/cloudbuild v1.16.5 h1:RvK5r8JBCLNg9XmfGPy05t3bmhLJV3Xh3sDHGHAATgM= cloud.google.com/go/cloudbuild v1.16.5/go.mod h1:HXLpZ8QeYZgmDIWpbl9Gs22p6o6uScgQ/cV9HF9cIZU= +cloud.google.com/go/cloudbuild v1.16.6 h1:6kV/JpCSKq64KWuZMYWZ8/utSkifWfEtQ+EcPjWPPLs= +cloud.google.com/go/cloudbuild v1.16.6/go.mod h1:Y7+6WFO8pT53rG0Lve6OZoO4+RkVTHGnHG7EB3uNiQw= cloud.google.com/go/clouddms v1.7.4 h1:Sr0Zo5EAcPQiCBgHWICg3VGkcdS/LLP1d9SR7qQBM/s= cloud.google.com/go/clouddms v1.7.10 h1:EA3y9v5TZiAlwgHJh2vPOEelqYiCxXBYZRCNnGK5q+g= cloud.google.com/go/clouddms v1.7.10/go.mod h1:PzHELq0QDyA7VaD9z6mzh2mxeBz4kM6oDe8YxMxd4RA= +cloud.google.com/go/clouddms v1.7.11 h1:pc78L2+BP6ex67gHqr1YjJ3uGo9gKLRCYk2hzzs9P2g= +cloud.google.com/go/clouddms v1.7.11/go.mod h1:rPNK0gJEkF2//rdxhCKhx+IFBlzkObOZhlhvDY1JKCE= cloud.google.com/go/cloudtasks v1.12.6 h1:EUt1hIZ9bLv8Iz9yWaCrqgMnIU+Tdh0yXM1MMVGhjfE= cloud.google.com/go/cloudtasks v1.12.12 h1:p91Brp4nJkyRRI/maYdO+FT+e9tU+2xoGr20s2rvalU= cloud.google.com/go/cloudtasks v1.12.12/go.mod h1:8UmM+duMrQpzzRREo0i3x3TrFjsgI/3FQw3664/JblA= +cloud.google.com/go/cloudtasks v1.12.13 h1:SN2NqXSOdmQzQJjoMV0qLIn6GXG5SzRrRVNrNq2Q6zA= +cloud.google.com/go/cloudtasks v1.12.13/go.mod h1:53OmmKqQTocrbeCL13cuaryBQOflyO8s4NxuRHJlXgc= cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute v1.27.4 h1:XM8ulx6crjdl09XBfji7viFgZOEQuIxBwKmjRH9Rtmc= cloud.google.com/go/compute v1.27.4/go.mod h1:7JZS+h21ERAGHOy5qb7+EPyXlQwzshzrx1x6L9JhTqU= +cloud.google.com/go/compute v1.27.5 h1:iii9Z+FhEeZ5cUkGOEqU+GM7MJSyxMgbE7H7j+JndYY= +cloud.google.com/go/compute v1.27.5/go.mod h1:DfwDGujFTdSeiE8b8ZqadF/uxHFBz+ekGsk8Zfi9dTA= cloud.google.com/go/contactcenterinsights v1.13.0 h1:6Vs/YnDG5STGjlWMEjN/xtmft7MrOTOnOZYUZtGTx0w= cloud.google.com/go/contactcenterinsights v1.13.6 h1:LRcI5RAlLIbjwT312sGt+gyXcaXTr+v7uEQlNyArO9g= cloud.google.com/go/contactcenterinsights v1.13.6/go.mod h1:mL+DbN3pMQGaAbDC4wZhryLciwSwHf5Tfk4Itr72Zyk= +cloud.google.com/go/contactcenterinsights v1.13.7 h1:KAqbmVHi77C5DwQ5ahpI41czo7LO2AWe0QJLDPfaVmY= +cloud.google.com/go/contactcenterinsights v1.13.7/go.mod h1:N5D7yxGknC0pDUC1OKOLShGQwpidKizKu3smt08153U= cloud.google.com/go/container v1.31.0 h1:MAaNH7VRNPWEhvqOypq2j+7ONJKrKzon4v9nS3nLZe0= cloud.google.com/go/container v1.38.0 h1:GP5zLamfvPZeOTifnGBSER/br76D5eJ97xhcXXrh5tM= cloud.google.com/go/container v1.38.0/go.mod h1:U0uPBvkVWOJGY/0qTVuPS7NeafFEUsHSPqT5pB8+fCY= +cloud.google.com/go/container v1.38.1 h1:Pb0GbZIg/KS4A9gbF3J4JHmrgPpBA2y+4v9N04aJkOs= +cloud.google.com/go/container v1.38.1/go.mod h1:2r4Qiz6IG2LhRFfWhPNmrYD7yzdE2B2kghigVWoSw/g= cloud.google.com/go/containeranalysis v0.11.4 h1:doJ0M1ljS4hS0D2UbHywlHGwB7sQLNrt9vFk9Zyi7vY= cloud.google.com/go/containeranalysis v0.12.1 h1:Xb8Eu7vVmWR5nAl5WPTGTx/dCr+R+oF7VbuYV47EHHs= cloud.google.com/go/containeranalysis v0.12.1/go.mod h1:+/lcJIQSFt45TC0N9Nq7/dPbl0isk6hnC4EvBBqyXsM= +cloud.google.com/go/containeranalysis v0.12.2 h1:BE8mBsV41BgUFQO3QW9wdpF3s5owx8idOcJ3I2aAoQA= +cloud.google.com/go/containeranalysis v0.12.2/go.mod h1:XF/U1ZJ9kXfl8HWRzuWMtEtzBb8SvJ0zvySrxrQA3N0= cloud.google.com/go/datacatalog v1.19.3 h1:A0vKYCQdxQuV4Pi0LL9p39Vwvg4jH5yYveMv50gU5Tw= cloud.google.com/go/datacatalog v1.21.0 h1:vl0pQT9TZ5rKi9e69FgtXNCR7I8MVRj4+CnbeXhz6UQ= cloud.google.com/go/datacatalog v1.21.0/go.mod h1:DB0QWF9nelpsbB0eR/tA0xbHZZMvpoFD1XFy3Qv/McI= +cloud.google.com/go/datacatalog v1.21.1 h1:l8yPkaMTlIX/437kBKGURvk4dtZIbotHBuSX2nLbJY8= +cloud.google.com/go/datacatalog v1.21.1/go.mod h1:23qsWWm592aQHwZ4or7VDjNhx7DeNklHAPE3GM47d1U= cloud.google.com/go/dataflow v0.9.5 h1:RYHtcPhmE664+F0Je46p+NvFbG8z//KCXp+uEqB4jZU= cloud.google.com/go/dataflow v0.9.11 h1:YIhStasKFDESaUdpnsHsp/5bACYL/yvW0OuZ6zPQ6nY= cloud.google.com/go/dataflow v0.9.11/go.mod h1:CCLufd7I4pPfyp54qMgil/volrL2ZKYjXeYLfQmBGJs= +cloud.google.com/go/dataflow v0.9.12 h1:p80cphmUBav+Htfr9DSQf++P0s8FrQT4BKsGmvYXBxM= +cloud.google.com/go/dataflow v0.9.12/go.mod h1:+2+80N2FOdDFWYhZdC2uTlX7GHP5kOH4vPNtfadggqQ= cloud.google.com/go/dataform v0.9.2 h1:5e4eqGrd0iDTCg4Q+VlAao5j2naKAA7xRurNtwmUknU= cloud.google.com/go/dataform v0.9.8 h1:oNtTx9PdH7aPnvrKIsPrh+Y6Mw+8Bw5/ZgLWVHAev/c= cloud.google.com/go/dataform v0.9.8/go.mod h1:cGJdyVdunN7tkeXHPNosuMzmryx55mp6cInYBgxN3oA= +cloud.google.com/go/dataform v0.9.9 h1:4aZ5O9aBHXUgQFZfu4sKjgIJIpzunbxZ1y8GHgtQZG8= +cloud.google.com/go/dataform v0.9.9/go.mod h1:QkiXNcrbFGjYtPtTkn700sfBiGIOG4mmpt26Ds8Ixeg= cloud.google.com/go/datafusion v1.7.5 h1:HQ/BUOP8OIGJxuztpYvNvlb+/U+/Bfs9SO8tQbh61fk= cloud.google.com/go/datafusion v1.7.11 h1:GVcVisjVKmoj1eNnIp3G3qjjo+7koHr0Kf8tF6Cjqe0= cloud.google.com/go/datafusion v1.7.11/go.mod h1:aU9zoBHgYmoPp4dzccgm/Gi4xWDMXodSZlNZ4WNeptw= +cloud.google.com/go/datafusion v1.7.12 h1:O5p8qgJg+7sn55JnaEnRr2yMX37bOZTMp3GBOa6dG0o= +cloud.google.com/go/datafusion v1.7.12/go.mod h1:ZUaEMjNVppM5ZasVt87QE0jN57O0LKY3uFe67EQ0GGI= cloud.google.com/go/datalabeling v0.8.5 h1:GpIFRdm0qIZNsxqURFJwHt0ZBJZ0nF/mUVEigR7PH/8= cloud.google.com/go/datalabeling v0.8.11 h1:7jSuJEAc7upeMmyICzqfU0OyxUV38JSWW+8r5GmoHX0= cloud.google.com/go/datalabeling v0.8.11/go.mod h1:6IGUV3z7hlkAU5ndKVshv/8z+7pxE+k0qXsEjyzO1Xg= +cloud.google.com/go/datalabeling v0.8.12 h1:iC7Lpzya3QKVLUy8M2J4y+JZrjAFtHg8bvAuLhMpkGw= +cloud.google.com/go/datalabeling v0.8.12/go.mod h1:IBbWnl80akCFj7jZ89/dRB/juuXig+QrQoLg24+vidg= cloud.google.com/go/dataplex v1.14.2 h1:fxIfdU8fxzR3clhOoNI7XFppvAmndxDu1AMH+qX9WKQ= cloud.google.com/go/dataplex v1.18.2 h1:bIU1r1YnsX6P1qTnaRnah/STHoLJ3EHUZVCjJl2+1Eo= cloud.google.com/go/dataplex v1.18.2/go.mod h1:NuBpJJMGGQn2xctX+foHEDKRbizwuiHJamKvvSteY3Q= +cloud.google.com/go/dataplex v1.18.3 h1:jYcAzyFS1DcnpwBVfnUD8wrRlltgU5L1EQdPshCEO+o= +cloud.google.com/go/dataplex v1.18.3/go.mod h1:wcfVhUr529uu9aZSy9WIUUdOCrkB8M5Gikfh3YUuGtE= cloud.google.com/go/dataproc v1.12.0 h1:W47qHL3W4BPkAIbk4SWmIERwsWBaNnWm0P2sdx3YgGU= cloud.google.com/go/dataproc/v2 v2.4.0 h1:/u81Fd+BvCLp+xjctI1DiWVJn6cn9/s3Akc8xPH02yk= cloud.google.com/go/dataproc/v2 v2.5.3 h1:OgTfUARkF8AfkNmoyT0wyLLXNh4LbT3l55s5gUlvFOk= cloud.google.com/go/dataproc/v2 v2.5.3/go.mod h1:RgA5QR7v++3xfP7DlgY3DUmoDSTaaemPe0ayKrQfyeg= +cloud.google.com/go/dataproc/v2 v2.5.4 h1:otFEJPOxzbAniKw4Aa1GVJlxjejR4/qHBlmU+xhY6MI= +cloud.google.com/go/dataproc/v2 v2.5.4/go.mod h1:rpxihxKtWjPl8MDwjGiYgMva8nEWQSyzvl3e0p4ATt4= cloud.google.com/go/dataqna v0.8.5 h1:9ybXs3nr9BzxSGC04SsvtuXaHY0qmJSLIpIAbZo9GqQ= cloud.google.com/go/dataqna v0.8.11 h1:bEUidOYRS0EQ7qHbZtcnospuks72iTapboszXU9poz8= cloud.google.com/go/dataqna v0.8.11/go.mod h1:74Icl1oFKKZXPd+W7YDtqJLa+VwLV6wZ+UF+sHo2QZQ= +cloud.google.com/go/dataqna v0.8.12 h1:bTiS9ppeA86EnJnXqZZLiQWXglFpyaF2TK/iPkZ/ga0= +cloud.google.com/go/dataqna v0.8.12/go.mod h1:86JdVMqh3521atZY1P7waaa50vzIbErTLY7gsio+umg= cloud.google.com/go/datastore v1.15.0 h1:0P9WcsQeTWjuD1H14JIY7XQscIPQ4Laje8ti96IC5vg= cloud.google.com/go/datastore v1.17.1 h1:6Me8ugrAOAxssGhSo8im0YSuy4YvYk4mbGvCadAH5aE= cloud.google.com/go/datastore v1.17.1/go.mod h1:mtzZ2HcVtz90OVrEXXGDc2pO4NM1kiBQy8YV4qGe0ZM= +cloud.google.com/go/datastore v1.19.0 h1:p5H3bUQltOa26GcMRAxPoNwoqGkq5v8ftx9/ZBB35MI= +cloud.google.com/go/datastore v1.19.0/go.mod h1:KGzkszuj87VT8tJe67GuB+qLolfsOt6bZq/KFuWaahc= cloud.google.com/go/datastream v1.10.4 h1:o1QDKMo/hk0FN7vhoUQURREuA0rgKmnYapB+1M+7Qz4= cloud.google.com/go/datastream v1.10.10 h1:klGhjQCLoLIRHMzMFIqM73cPNKliGveqC+Vrms+ce6A= cloud.google.com/go/datastream v1.10.10/go.mod h1:NqchuNjhPlISvWbk426/AU/S+Kgv7srlID9P5XOAbtg= +cloud.google.com/go/datastream v1.10.11 h1:LpJhP4g8+JGO5dKwhVSblnpB1hk/qA2/+rq68ppkVF8= +cloud.google.com/go/datastream v1.10.11/go.mod h1:0d9em/ERaof15lY5JU3pWKF7ZJOHiPKcNJsTCBz6TX8= cloud.google.com/go/deploy v1.17.1 h1:m27Ojwj03gvpJqCbodLYiVmE9x4/LrHGGMjzc0LBfM4= cloud.google.com/go/deploy v1.21.0 h1:/qnNETfztKemA9JmUBOrnH/rG/XFkHOBHygN1Vy5lkg= cloud.google.com/go/deploy v1.21.0/go.mod h1:PaOfS47VrvmYnxG5vhHg0KU60cKeWcqyLbMBjxS8DW8= +cloud.google.com/go/deploy v1.21.2 h1:sperWx8Nk3AFnonH8XXxCdarZfeXZYR7dgmDFoBkuCc= +cloud.google.com/go/deploy v1.21.2/go.mod h1:BDBWUXXCBGrvYxVmSYXIRdNffioym0ChQWDQS0c/wA8= cloud.google.com/go/dialogflow v1.49.0 h1:KqG0oxGE71qo0lRVyAoeBozefCvsMfcDzDjoLYSY0F4= cloud.google.com/go/dialogflow v1.55.0 h1:H28O0WAm2waHpNAz2n9jbv8FApfXxeKAkfHObdP2MMk= cloud.google.com/go/dialogflow v1.55.0/go.mod h1:0u0hSlJiFpMkMpMNoFrQETwDjaRm8Q8hYKv+jz5JeRA= +cloud.google.com/go/dialogflow v1.56.0 h1:s4lhL0DZExduaN534Rl3K488sKkes7LHnDQtbpwFHNk= +cloud.google.com/go/dialogflow v1.56.0/go.mod h1:P1hIske3kr9pSl11nEP4tFfAu2E4US+7PpboeBhM4ag= cloud.google.com/go/dlp v1.11.2 h1:lTipOuJaSjlYnnotPMbEhKURLC6GzCMDDzVbJAEbmYM= cloud.google.com/go/dlp v1.16.0 h1:mYjBqgVjseYXlx1TOOFsxSeZLboqxxKR7TqRGOG9vIU= cloud.google.com/go/dlp v1.16.0/go.mod h1:LtPZxZAenBXKzvWIOB2hdHIXuEcK0wW0En8//u+/nNA= +cloud.google.com/go/dlp v1.17.0 h1:BrKrhNjAi5u8EgIadv1mcjEX4bB7FPPcRvr0Cf9bdN4= +cloud.google.com/go/dlp v1.17.0/go.mod h1:9LuCkaCRZxWZ6HyqkmV3/PW0gKIVKoUVNjf0yMKVqMs= cloud.google.com/go/documentai v1.25.0 h1:lI62GMEEPO6vXJI9hj+G9WjOvnR0hEjvjokrnex4cxA= cloud.google.com/go/documentai v1.31.0 h1:YRkFK+0ZgEciz1svDkuL9fjbQLq8xvVa1d3NUlhO6B4= cloud.google.com/go/documentai v1.31.0/go.mod h1:5ajlDvaPyl9tc+K/jZE8WtYIqSXqAD33Z1YAYIjfad4= +cloud.google.com/go/documentai v1.32.0 h1:bXTTAjRmu7oVlvLqV4lLc7VKqR/IUtgexBPyLDWUs/o= +cloud.google.com/go/documentai v1.32.0/go.mod h1:X8skObtXBvR31QF+jERAu4mOCpRiJBaqbMvB3FLnMsA= cloud.google.com/go/domains v0.9.5 h1:Mml/R6s3vQQvFPpi/9oX3O5dRirgjyJ8cksK8N19Y7g= cloud.google.com/go/domains v0.9.11 h1:8peNiXtaMNIF9Wybci859M/yprFcEve1R2z08pErUBs= cloud.google.com/go/domains v0.9.11/go.mod h1:efo5552kUyxsXEz30+RaoIS2lR7tp3M/rhiYtKXkhkk= +cloud.google.com/go/domains v0.9.12 h1:Ot7K4Vl4Ap/y90VYjyz9qL57e+pAhMYVP0bIM7YnPvI= +cloud.google.com/go/domains v0.9.12/go.mod h1:2YamnZleyO3y5zYV+oASWAUoiHBJ0ZmkEcO6MXs5x3c= cloud.google.com/go/edgecontainer v1.1.5 h1:tBY32km78ScpK2aOP84JoW/+wtpx5WluyPUSEE3270U= cloud.google.com/go/edgecontainer v1.2.5 h1:wTo0ulZDSsDzeoVjICJZjZMzZ1Nn9y//AwAQlXbaTbs= cloud.google.com/go/edgecontainer v1.2.5/go.mod h1:OAb6tElD3F3oBujFAup14PKOs9B/lYobTb6LARmoACY= +cloud.google.com/go/edgecontainer v1.2.6 h1:r/4Yqg3Kji26XbCegwta1c7C92uwO0TUSaTwbzG5s/w= +cloud.google.com/go/edgecontainer v1.2.6/go.mod h1:4jyHt4ytGLL8P0S3m6umOL8bJhTw4tVnDUcPQCGlNMM= cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0= cloud.google.com/go/errorreporting v0.3.1 h1:E/gLk+rL7u5JZB9oq72iL1bnhVlLrnfslrgcptjJEUE= cloud.google.com/go/errorreporting v0.3.1/go.mod h1:6xVQXU1UuntfAf+bVkFk6nld41+CPyF2NSPCyXE3Ztk= cloud.google.com/go/essentialcontacts v1.6.6 h1:13eHn5qBnsawxI7mIrv4jRIEmQ1xg0Ztqw5ZGqtUNfA= cloud.google.com/go/essentialcontacts v1.6.12 h1:JaQXS+qCFYs8yectfZHpzw4+NjTvFqTuDMCtfPzMvbw= cloud.google.com/go/essentialcontacts v1.6.12/go.mod h1:UGhWTIYewH8Ma4wDRJp8cMAHUCeAOCKsuwd6GLmmQLc= +cloud.google.com/go/essentialcontacts v1.6.13 h1:zKttHKhAV6LxT/SlahypK+2hBjmIVg9elMn3r0WQ5cY= +cloud.google.com/go/essentialcontacts v1.6.13/go.mod h1:52AB7Qmi6TBzA/lsSZER7oi4jR/pY0TXC0lNaaAyfA4= cloud.google.com/go/eventarc v1.13.4 h1:ORkd6/UV5FIdA8KZQDLNZYKS7BBOrj0p01DXPmT4tE4= cloud.google.com/go/eventarc v1.13.10 h1:HVJmOVc+7eVFAqMpJRrq0nY0KlYBEBVZW7Gz7TxTio8= cloud.google.com/go/eventarc v1.13.10/go.mod h1:KlCcOMApmUaqOEZUpZRVH+p0nnnsY1HaJB26U4X5KXE= +cloud.google.com/go/eventarc v1.13.11 h1:bFkxnUwdOKKgXjCoxpwd9FYV/yBs8iUhIuiJV4R1jlE= +cloud.google.com/go/eventarc v1.13.11/go.mod h1:1PJ+icw2mJYgqUsICg7Cr8gzMw38f3THiSzVSNPFrNQ= cloud.google.com/go/filestore v1.8.1 h1:X5G4y/vrUo1B8Nsz93qSWTMAcM8LXbGUldq33OdcdCw= cloud.google.com/go/filestore v1.8.7 h1:LF9t5MClPyFJMuXdez/AjF1uyO9xHKUFF3GUqA+xFPI= cloud.google.com/go/filestore v1.8.7/go.mod h1:dKfyH0YdPAKdYHqAR/bxZeil85Y5QmrEVQwIYuRjcXI= +cloud.google.com/go/filestore v1.8.8 h1:ZPE2+k1eyesicuehhHRXEG7WDo3mW/0li8oNnmuyxYE= +cloud.google.com/go/filestore v1.8.8/go.mod h1:gNT7bpDZSOFWCnRirQw1IehZtA7blbzkO3Q8VQfkeZ0= cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw= cloud.google.com/go/firestore v1.16.0 h1:YwmDHcyrxVRErWcgxunzEaZxtNbc8QoFYA/JOEwDPgc= cloud.google.com/go/firestore v1.16.0/go.mod h1:+22v/7p+WNBSQwdSwP57vz47aZiY+HrDkrOsJNhk7rg= cloud.google.com/go/functions v1.16.0 h1:IWVylmK5F6hJ3R5zaRW7jI5PrWhCvtBVU4axQLmXSo4= cloud.google.com/go/functions v1.16.6 h1:tPe3/48RpjcFk96VeB6jOKQpK8nliGJLsgjh6pUOyFQ= cloud.google.com/go/functions v1.16.6/go.mod h1:wOzZakhMueNQaBUJdf0yjsJIe0GBRu+ZTvdSTzqHLs0= +cloud.google.com/go/functions v1.18.0 h1:50K2iLtj7xj6xqrhdNOL+aVaHwKi4h7qgNWP9ieTDag= +cloud.google.com/go/functions v1.18.0/go.mod h1:r8uxxI35hdP2slfTjGJvx04NRy8sP/EXUMZ0NYfBd+w= cloud.google.com/go/gaming v1.10.1 h1:5qZmZEWzMf8GEFgm9NeC3bjFRpt7x4S6U7oLbxaf7N8= cloud.google.com/go/gkebackup v1.3.5 h1:iuE8KNtTsPOc79qeWoNS8zOWoXPD9SAdOmwgxtlCmh8= cloud.google.com/go/gkebackup v1.5.4 h1:mufh0PNpvqbfLV+TcxzSGESX8jGBcjKgctldv7kwQns= cloud.google.com/go/gkebackup v1.5.4/go.mod h1:V+llvHlRD0bCyrkYaAMJX+CHralceQcaOWjNQs8/Ymw= +cloud.google.com/go/gkebackup v1.5.5 h1:ITiOPDl0Q1vgDHdbMvRk0Yk6uEcP8Kq875m6IMJJu6Y= +cloud.google.com/go/gkebackup v1.5.5/go.mod h1:C/XZ2LoG+V97xGc18oCPniO754E0iHt0OXqKatawBMM= cloud.google.com/go/gkeconnect v0.8.5 h1:17d+ZSSXKqG/RwZCq3oFMIWLPI8Zw3b8+a9/BEVlwH0= cloud.google.com/go/gkeconnect v0.8.11 h1:4bZAzvqhuv1uP+i4yG9cEMQ6ggdP26nBVjUgroPU6IM= cloud.google.com/go/gkeconnect v0.8.11/go.mod h1:ejHv5ehbceIglu1GsMwlH0nZpTftjxEY6DX7tvaM8gA= +cloud.google.com/go/gkeconnect v0.8.12 h1:0n3xfOvU+SN2LJRWex81U3xCNfQtPpxjSkrI3XBdudM= +cloud.google.com/go/gkeconnect v0.8.12/go.mod h1:+SpnnnUx4Xs/mWBJbqC7Mlu9Vv7riQlHSDS1T1ek2+U= cloud.google.com/go/gkehub v0.14.5 h1:RboLNFzf9wEMSo7DrKVBlf+YhK/A/jrLN454L5Tz99Q= cloud.google.com/go/gkehub v0.14.11 h1:hQkVCcOiW/vPVYsthvKl1nje430/TpdFfgeIuqcYVOA= cloud.google.com/go/gkehub v0.14.11/go.mod h1:CsmDJ4qbBnSPkoBltEubK6qGOjG0xNfeeT5jI5gCnRQ= +cloud.google.com/go/gkehub v0.14.12 h1:twVZpPzRnwJQ9UwU3M/Mwn356qboSRo+UxsTmlMtKiM= +cloud.google.com/go/gkehub v0.14.12/go.mod h1:CNYNBCqjIkE9L70gzbRxZOsc++Wcp2oCLkfuytOFqRM= cloud.google.com/go/gkemulticloud v1.1.1 h1:rsSZAGLhyjyE/bE2ToT5fqo1qSW7S+Ubsc9jFOcbhSI= cloud.google.com/go/gkemulticloud v1.2.4 h1:6zV05tyl37HoEjCGGY+zHFNxnKQCjvVpiqWAUVgGaEs= cloud.google.com/go/gkemulticloud v1.2.4/go.mod h1:PjTtoKLQpIRztrL+eKQw8030/S4c7rx/WvHydDJlpGE= +cloud.google.com/go/gkemulticloud v1.2.5 h1:OREoK+FO+5j6eVXdvGsiXHvoFkUZxxoS8WBWk6zWThA= +cloud.google.com/go/gkemulticloud v1.2.5/go.mod h1:zVRNlO7/jFXmvrkBd+UfhI2T7ZBb+N3b3lt/3K60uS0= cloud.google.com/go/grafeas v0.3.4 h1:D4x32R/cHX3MTofKwirz015uEdVk4uAxvZkZCZkOrF4= cloud.google.com/go/grafeas v0.3.6 h1:7bcA10EBgTsxeAVypJhz2Dv3fhrdlO7Ml8l7ZZA2IkE= cloud.google.com/go/grafeas v0.3.6/go.mod h1:to6ECAPgRO2xeqD8ISXHc70nObJuaKZThreQOjeOH3o= +cloud.google.com/go/grafeas v0.3.9 h1:4rfIkfgxFkhgzGc19aBGob+R6OXJVC7nZ+XrpOFTxYg= +cloud.google.com/go/grafeas v0.3.9/go.mod h1:j8hBcywIqtJ3/3QP9yYB/LqjLWBM9dXumBa+xplvyG0= cloud.google.com/go/gsuiteaddons v1.6.5 h1:CZEbaBwmbYdhFw21Fwbo+C35HMe36fTE0FBSR4KSfWg= cloud.google.com/go/gsuiteaddons v1.6.11 h1:zydWX0nVT0Ut/P1X25Sy+4Rqe2PH04IzhwlF1BJd8To= cloud.google.com/go/gsuiteaddons v1.6.11/go.mod h1:U7mk5PLBzDpHhgHv5aJkuvLp9RQzZFpa8hgWAB+xVIk= +cloud.google.com/go/gsuiteaddons v1.6.12 h1:lp9f1VVl7Z4S8uqWTvGvazsMhBFpEbUiqCG2uYJ3LRs= +cloud.google.com/go/gsuiteaddons v1.6.12/go.mod h1:hqTWzMXCgS/BPuyiWHzDBZC4K3+a9lcJWBUR+i+6D7A= cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= cloud.google.com/go/iam v1.1.12/go.mod h1:9LDX8J7dN5YRyzVHxwQzrQs9opFFqn0Mxs9nAeB+Hhg= cloud.google.com/go/iap v1.9.4 h1:94zirc2r4t6KzhAMW0R6Dme005eTP6yf7g6vN4IhRrA= cloud.google.com/go/iap v1.9.10 h1:j7jQqqSkZ2nWAOCiyaZfnJ+REycTJ2NP2dUEjLoW4aA= cloud.google.com/go/iap v1.9.10/go.mod h1:pO0FEirrhMOT1H0WVwpD5dD9r3oBhvsunyBQtNXzzc0= +cloud.google.com/go/iap v1.9.11 h1:rqm2jCKE/uA2iRYxcFY7O88sUBhru5+/OTK4dphIOyM= +cloud.google.com/go/iap v1.9.11/go.mod h1:UcvTLqySIc8C3Dw3JPZ7QihzzxVQJ7/KUOL9MjxiPZk= cloud.google.com/go/ids v1.4.5 h1:xd4U7pgl3GHV+MABnv1BF4/Vy/zBF7CYC8XngkOLzag= cloud.google.com/go/ids v1.4.11 h1:JhlR1d0XhMsj6YmSmbLbbXV5CGkffnUkPj0HNxJYNtc= cloud.google.com/go/ids v1.4.11/go.mod h1:+ZKqWELpJm8WcRRsSvKZWUdkriu4A3XsLLzToTv3418= +cloud.google.com/go/ids v1.4.12 h1:9X6gbqXgOztpxR9pl9xkBgG4jMex0oZDrpwaspCLL1k= +cloud.google.com/go/ids v1.4.12/go.mod h1:SH2yjlk9fKWrRgob/E0Gd1wM+VFztfTdR+LaJRDMiPw= cloud.google.com/go/iot v1.7.5 h1:munTeBlbqI33iuTYgXy7S8lW2TCgi5l1hA4roSIY+EE= cloud.google.com/go/iot v1.7.11 h1:UBqSUZA6+7bM+mv6uvhl8tVsyT2Fi50njtBFRbrKSlI= cloud.google.com/go/iot v1.7.11/go.mod h1:0vZJOqFy9kVLbUXwTP95e0dWHakfR4u5IWqsKMGIfHk= +cloud.google.com/go/iot v1.7.12 h1:udkAi3LvaD7KdwJUegnUyOBVnruL0It1nmV5TktYF7o= +cloud.google.com/go/iot v1.7.12/go.mod h1:8ntlg5OWnVodAsbs0KDLY58tKEroy+CYciDX/ONxpl4= cloud.google.com/go/kms v1.18.4/go.mod h1:SG1bgQ3UWW6/KdPo9uuJnzELXY5YTTMJtDYvajiQ22g= cloud.google.com/go/language v1.12.3 h1:iaJZg6K4j/2PvZZVcjeO/btcWWIllVRBhuTFjGO4LXs= cloud.google.com/go/language v1.13.0 h1:6Pl97Ei85A3wBJwjXW2S/1IWeUvhQf/lIPQBItnp0FA= cloud.google.com/go/language v1.13.0/go.mod h1:B9FbD17g1EkilctNGUDAdSrBHiFOlKNErLljO7jplDU= +cloud.google.com/go/language v1.13.1 h1:sgAhzmJ/wZBS/4djQJLpjke52sdDhfKuskoCHSTaCHk= +cloud.google.com/go/language v1.13.1/go.mod h1:PY/DAdVW0p2MWl2Lut31AJddEmQBBXMnPUM8nkl/WfA= cloud.google.com/go/lifesciences v0.9.5 h1:gXvN70m2p+4zgJFzaz6gMKaxTuF9WJ0USYoMLWAOm8g= cloud.google.com/go/lifesciences v0.9.11 h1:xyPSYICJWZElcELYgWCKs5PltyNX3TzOKaQAZA7d/I0= cloud.google.com/go/lifesciences v0.9.11/go.mod h1:NMxu++FYdv55TxOBEvLIhiAvah8acQwXsz79i9l9/RY= +cloud.google.com/go/lifesciences v0.9.12 h1:DGKhxamDcn1v7ieat3sqCjm6HwJqWnrF9Xbq/IDyz80= +cloud.google.com/go/lifesciences v0.9.12/go.mod h1:si0In2nxVPtZnSoDNlEgSV4BJWxxlkdgKh+LXPYMf4w= cloud.google.com/go/logging v1.9.0 h1:iEIOXFO9EmSiTjDmfpbRjOxECO7R8C7b8IXUGOj7xZw= cloud.google.com/go/logging v1.11.0 h1:v3ktVzXMV7CwHq1MBF65wcqLMA7i+z3YxbUsoK7mOKs= cloud.google.com/go/logging v1.11.0/go.mod h1:5LDiJC/RxTt+fHc1LAt20R9TKiUTReDg6RuuFOZ67+A= @@ -214,18 +330,28 @@ cloud.google.com/go/longrunning v0.5.11/go.mod h1:rDn7//lmlfWV1Dx6IB4RatCPenTwwm cloud.google.com/go/managedidentities v1.6.5 h1:+bpih1piZVLxla/XBqeSUzJBp8gv9plGHIMAI7DLpDM= cloud.google.com/go/managedidentities v1.6.11 h1:YU6NtRRBX5R1f3a8ryqhh1dUb1/pt3rnhSO50b63yZY= cloud.google.com/go/managedidentities v1.6.11/go.mod h1:df+8oZ1D4Eri+NrcpuiR5Hd6MGgiMqn0ZCzNmBYPS0A= +cloud.google.com/go/managedidentities v1.6.12 h1:p+n5vvhcpWgwpHoeeUoe+D9/wzIqW5vsWoi2n7YTafA= +cloud.google.com/go/managedidentities v1.6.12/go.mod h1:7KrCfXlxPw85nhlEYF3o5oLC8RtQakMAIGKNiNN3OAg= cloud.google.com/go/maps v1.6.4 h1:EVCZAiDvog9So46460BGbCasPhi613exoaQbpilMVlk= cloud.google.com/go/maps v1.11.6 h1:HMI0drvgnT+BtsjBofb1Z80P53n63ybmm7l+1w1og9I= cloud.google.com/go/maps v1.11.6/go.mod h1:MOS/NN0L6b7Kumr8bLux9XTpd8+D54DYxBMUjq+XfXs= +cloud.google.com/go/maps v1.11.7 h1:ifdbRNVte+Oq0aHVR4lvXMBSvJhtIcK+G9GsWRQDQ9o= +cloud.google.com/go/maps v1.11.7/go.mod h1:CEGHM/Q0epp0oWFO7kiEk8oDGUUhjd1sj4Rcd/4iwGU= cloud.google.com/go/mediatranslation v0.8.5 h1:c76KdIXljQHSCb/Cy47S8H4s05A4zbK3pAFGzwcczZo= cloud.google.com/go/mediatranslation v0.8.11 h1:QvO405ocKTmcJqjfqL1zps08yrKk8rE+0E1ZNSWfjbw= cloud.google.com/go/mediatranslation v0.8.11/go.mod h1:3sNEm0fx61eHk7rfzBzrljVV9XKr931xI3OFacQBVFg= +cloud.google.com/go/mediatranslation v0.8.12 h1:26qFQZxj9Rii22kl84HHcJ0zWlaHsVdBJZxAil89ejs= +cloud.google.com/go/mediatranslation v0.8.12/go.mod h1:owrIOMto4hzsoqkZe95ePEiMJv4JF7/tgEgWuHC+t40= cloud.google.com/go/memcache v1.10.5 h1:yeDv5qxRedFosvpMSEswrqUsJM5OdWvssPHFliNFTc4= cloud.google.com/go/memcache v1.10.11 h1:DGPEJOVL4Qix2GLKQKcgzGpNLD7gAnCFLr9ch9YSIhU= cloud.google.com/go/memcache v1.10.11/go.mod h1:ubJ7Gfz/xQawQY5WO5pht4Q0dhzXBFeEszAeEJnwBHU= +cloud.google.com/go/memcache v1.10.12 h1:rQxkJUKO9YlENBUHb9WuSb6vBlOrU5xh9Riz81haxW0= +cloud.google.com/go/memcache v1.10.12/go.mod h1:OfG2zgIXVTNJy2UKDF4o4irKxBqTx9RMZhGKJ/hLJUI= cloud.google.com/go/metastore v1.13.4 h1:dR7vqWXlK6IYR8Wbu9mdFfwlVjodIBhd1JRrpZftTEg= cloud.google.com/go/metastore v1.13.10 h1:E5eAxzIRoVP0DrV+ZtTLMYkkjSs4fcfsbL7wv1mXV2U= cloud.google.com/go/metastore v1.13.10/go.mod h1:RPhMnBxUmTLT1fN7fNbPqtH5EoGHueDxubmJ1R1yT84= +cloud.google.com/go/metastore v1.13.11 h1:yZR2paCUcLscxQLp35FoApsMOFB7pOGcIJTiX6psnlc= +cloud.google.com/go/metastore v1.13.11/go.mod h1:aeP+V0Xs3SLqu4mrQWRyuSg5+fdyPq+kdu1xclnR8y8= cloud.google.com/go/monitoring v1.18.0 h1:NfkDLQDG2UR3WYZVQE8kwSbUIEyIqJUPl+aOQdFH1T4= cloud.google.com/go/monitoring v1.20.3/go.mod h1:GPIVIdNznIdGqEjtRKQWTLcUeRnPjZW85szouimiczU= cloud.google.com/go/monitoring v1.20.4 h1:zwcViK7mT9SV0kzKqLOI3spRadvsmvw/R9z1MHNeC0E= @@ -233,42 +359,68 @@ cloud.google.com/go/monitoring v1.20.4/go.mod h1:v7F/UcLRw15EX7xq565N7Ae5tnYEE28 cloud.google.com/go/networkconnectivity v1.14.4 h1:GBfXFhLyPspnaBE3nI/BRjdhW8vcbpT9QjE/4kDCDdc= cloud.google.com/go/networkconnectivity v1.14.10 h1:2EE8pKiv1AI8fBdZCdiUjNgQ+TaBgwE4GxIze4fDdY0= cloud.google.com/go/networkconnectivity v1.14.10/go.mod h1:f7ZbGl4CV08DDb7lw+NmMXQTKKjMhgCEEwFbEukWuOY= +cloud.google.com/go/networkconnectivity v1.14.11 h1:zkOTU4GJQQVOD2bKTlUPFIdEG1MQCgNrnwagL43uK8s= +cloud.google.com/go/networkconnectivity v1.14.11/go.mod h1:XRA6nT7ygTN09gAtCRsFhbqn3u7/9LIUn6S+5G4fs50= cloud.google.com/go/networkmanagement v1.9.4 h1:aLV5GcosBNmd6M8+a0ekB0XlLRexv4fvnJJrYnqeBcg= cloud.google.com/go/networkmanagement v1.13.6 h1:6TGn7ZZXyj5rloN0vv5Aw0awYbfbheNRg8BKroT7/2g= cloud.google.com/go/networkmanagement v1.13.6/go.mod h1:WXBijOnX90IFb6sberjnGrVtZbgDNcPDUYOlGXmG8+4= +cloud.google.com/go/networkmanagement v1.13.7 h1:dXfIaWKr5vVBBHagmbILBkb7yV+FEsyZmMuTZmG3frk= +cloud.google.com/go/networkmanagement v1.13.7/go.mod h1:foi1eLe3Ayydrr63O3ViMwG1AGS3/BxRSmXpAqMFhkY= cloud.google.com/go/networksecurity v0.9.5 h1:+caSxBTj0E8OYVh/5wElFdjEMO1S/rZtE1152Cepchc= cloud.google.com/go/networksecurity v0.9.11 h1:6wUzyHCwDEOkDbAJjT6jxsAi+vMfe3aj2JWwqSFVXOQ= cloud.google.com/go/networksecurity v0.9.11/go.mod h1:4xbpOqCwplmFgymAjPFM6ZIplVC6+eQ4m7sIiEq9oJA= +cloud.google.com/go/networksecurity v0.9.12 h1:BqYfZZHx2koUMiRqEz3BV9AVOsreleSOELi+FZqrEUw= +cloud.google.com/go/networksecurity v0.9.12/go.mod h1:Id0HGMKFJemLolvsoECda71vU2T9JByGPYct6LgMxrw= cloud.google.com/go/notebooks v1.11.3 h1:FH48boYmrWVQ6k0Mx/WrnNafXncT5iSYxA8CNyWTgy0= cloud.google.com/go/notebooks v1.11.9 h1:c8I0EaLGqStRmvX29L7jb4mOrpigxn1mGyBt65OdS0s= cloud.google.com/go/notebooks v1.11.9/go.mod h1:JmnRX0eLgHRJiyxw8HOgumW9iRajImZxr7r75U16uXw= +cloud.google.com/go/notebooks v1.11.10 h1:7FOp+bFhy1WYKbRpfb190Jhj5Qu4paXv5EErwOD1bFY= +cloud.google.com/go/notebooks v1.11.10/go.mod h1:2d3Lwdm5VTxZzxY94V8TffNBk0FBnORieiVBeN+n9QQ= cloud.google.com/go/optimization v1.6.3 h1:63NZaWyN+5rZEKHPX4ACpw3BjgyeuY8+rCehiCMaGPY= cloud.google.com/go/optimization v1.6.9 h1:++U21U9LWFdgnnVFaq4kDeOafft6gI/CHzsiJ173c6U= cloud.google.com/go/optimization v1.6.9/go.mod h1:mcvkDy0p4s5k7iSaiKrwwpN0IkteHhGmuW5rP9nXA5M= +cloud.google.com/go/optimization v1.6.10 h1:jsPO26IqwEs/x3KJQCmHvL9/gQK35JppdxNbuyXPh5Q= +cloud.google.com/go/optimization v1.6.10/go.mod h1:qWX4Kv90NeBgPfoRwyMbISe8M7Ql1LAOFPNFuOqIvUI= cloud.google.com/go/orchestration v1.8.5 h1:YHgWMlrPttIVGItgGfuvO2KM7x+y9ivN/Yk92pMm1a4= cloud.google.com/go/orchestration v1.9.6 h1:xfczjtNDabsXTnDySAwD/TMfDSkcxEgH1rxfS6BVQtM= cloud.google.com/go/orchestration v1.9.6/go.mod h1:gQvdIsHESZJigimnbUA8XLbYeFlSg/z+A7ppds5JULg= +cloud.google.com/go/orchestration v1.9.7 h1:6KCe2V5E9gCtN09BEzLVTCv8g16LPYzImDqgwXKbnvY= +cloud.google.com/go/orchestration v1.9.7/go.mod h1:Mgtuci4LszRSzKkQucdWvdhTyG+QB4+3ZpsZ4sqalrQ= cloud.google.com/go/orgpolicy v1.12.1 h1:2JbXigqBJVp8Dx5dONUttFqewu4fP0p3pgOdIZAhpYU= cloud.google.com/go/orgpolicy v1.12.7 h1:StymaN9vS7949m15Nwgf5aKd9yaRtzWJ4VqHdbXcOEM= cloud.google.com/go/orgpolicy v1.12.7/go.mod h1:Os3GlUFRPf1UxOHTup5b70BARnhHeQNNVNZzJXPbWYI= +cloud.google.com/go/orgpolicy v1.12.8 h1:lBKGvA07J42nQpU6X61hQDIv/jcnuJtz/BhnTjGIDYg= +cloud.google.com/go/orgpolicy v1.12.8/go.mod h1:WHkLGqHILPnMgJ4UTdag6YgztVIgWS+T5T6tywH3cSM= cloud.google.com/go/osconfig v1.12.5 h1:Mo5jGAxOMKH/PmDY7fgY19yFcVbvwREb5D5zMPQjFfo= cloud.google.com/go/osconfig v1.13.2 h1:IbbTg7jtTEn4+iEJwgbCYck5NLMOc2eKrqVpQb7Xx6c= cloud.google.com/go/osconfig v1.13.2/go.mod h1:eupylkWQJCwSIEMkpVR4LqpgKkQi0mD4m1DzNCgpQso= +cloud.google.com/go/osconfig v1.13.3 h1:GoiK/q0OAhaGxZMMapulq+lxZU4BEZn8ado2g3yqfqc= +cloud.google.com/go/osconfig v1.13.3/go.mod h1:gIFyyriC1ANob8SnpwrQ6jjNroRwItoBOYfqiG3LkUU= cloud.google.com/go/oslogin v1.13.1 h1:1K4nOT5VEZNt7XkhaTXupBYos5HjzvJMfhvyD2wWdFs= cloud.google.com/go/oslogin v1.13.7 h1:q9x7tjKtfBpXMpiJKwb5UyhMA3GrwmJHvx56uCEuS8M= cloud.google.com/go/oslogin v1.13.7/go.mod h1:xq027cL0fojpcEcpEQdWayiDn8tIx3WEFYMM6+q7U+E= +cloud.google.com/go/oslogin v1.13.8 h1:ukF32m5YIOUgMQXrJW6RkOLxV/VYPa3f1mDr9OjN8bA= +cloud.google.com/go/oslogin v1.13.8/go.mod h1:rc52yAdMXB5mERVeOXRcDnaswQNFTPRJ93VVHmGwJSk= cloud.google.com/go/phishingprotection v0.8.5 h1:DH3WFLzEoJdW/6xgsmoDqOwT1xddFi7gKu0QGZQhpGU= cloud.google.com/go/phishingprotection v0.8.11 h1:3Kr7TINZ+8pbdWe3JnJf9c84ibz60NRTvwLdVtI3SK8= cloud.google.com/go/phishingprotection v0.8.11/go.mod h1:Mge0cylqVFs+D0EyxlsTOJ1Guf3qDgrztHzxZqkhRQM= +cloud.google.com/go/phishingprotection v0.8.12 h1:64kH4KgKV4vYJeAqN9dHbxPLFE5yEKcfvV3Rrh0TZTg= +cloud.google.com/go/phishingprotection v0.8.12/go.mod h1:tkR+cZBpRdu4i04BP1CqaZr2yL7U1o8t+v/SZ2kOSDU= cloud.google.com/go/policytroubleshooter v1.10.3 h1:c0WOzC6hz964QWNBkyKfna8A2jOIx1zzZa43Gx/P09o= cloud.google.com/go/policytroubleshooter v1.10.9 h1:EHXkBYgHQtVH8P41G2xxmQbMwQh+o5ggno8l3/9CXaA= cloud.google.com/go/policytroubleshooter v1.10.9/go.mod h1:X8HEPVBWz8E+qwI/QXnhBLahEHdcuPO3M9YvSj0LDek= +cloud.google.com/go/policytroubleshooter v1.10.10 h1:oIc5msMHCZgiYbMJPMuqhj478Eo0oT6HkUnLmYBz/rc= +cloud.google.com/go/policytroubleshooter v1.10.10/go.mod h1:9S7SKOsLydGB2u91WKNjHpLScxxkKATIu3Co0fw8LPQ= cloud.google.com/go/privatecatalog v0.9.5 h1:UZ0assTnATXSggoxUIh61RjTQ4P9zCMk/kEMbn0nMYA= cloud.google.com/go/privatecatalog v0.9.11 h1:t8dJpQf22H6COeDvp7TDl7+KuwLT6yVmqAVRIUIUj6U= cloud.google.com/go/privatecatalog v0.9.11/go.mod h1:awEF2a8M6UgoqVJcF/MthkF8SSo6OoWQ7TtPNxUlljY= +cloud.google.com/go/privatecatalog v0.9.12 h1:ZmATFJMFK6gbWoDQpLX9y6nmBMeYUCY8Wa5ijc2yKss= +cloud.google.com/go/privatecatalog v0.9.12/go.mod h1:Sl292f/1xY0igI+CFNGfiXJWiN9BvaLpc8mjnCHNRnA= cloud.google.com/go/pubsub v1.36.1 h1:dfEPuGCHGbWUhaMCTHUFjfroILEkx55iUmKBZTP5f+Y= cloud.google.com/go/pubsub v1.41.0 h1:ZPaM/CvTO6T+1tQOs/jJ4OEMpjtel0PTLV7j1JK+ZrI= cloud.google.com/go/pubsub v1.41.0/go.mod h1:g+YzC6w/3N91tzG66e2BZtp7WrpBBMXVa3Y9zVoOGpk= +cloud.google.com/go/pubsub v1.42.0 h1:PVTbzorLryFL5ue8esTS2BfehUs0ahyNOY9qcd+HMOs= +cloud.google.com/go/pubsub v1.42.0/go.mod h1:KADJ6s4MbTwhXmse/50SebEhE4SmUwHi48z3/dHar1Y= cloud.google.com/go/pubsublite v1.8.1 h1:pX+idpWMIH30/K7c0epN6V703xpIcMXWRjKJsz0tYGY= cloud.google.com/go/pubsublite v1.8.2 h1:jLQozsEVr+c6tOU13vDugtnaBSUy/PD5zK6mhm+uF1Y= cloud.google.com/go/pubsublite v1.8.2/go.mod h1:4r8GSa9NznExjuLPEJlF1VjOPOpgf3IT6k8x/YgaOPI= @@ -276,30 +428,48 @@ cloud.google.com/go/recaptchaenterprise v1.3.1 h1:u6EznTGzIdsyOsvm+Xkw0aSuKFXQly cloud.google.com/go/recaptchaenterprise/v2 v2.9.2 h1:U3Wfq12X9cVMuTpsWDSURnXF0Z9hSPTHj+xsnXDRLsw= cloud.google.com/go/recaptchaenterprise/v2 v2.14.2 h1:80Mx0i3uyv5dPNUYsNPFk9GJ+19AmTlnWnXFCTC9NkI= cloud.google.com/go/recaptchaenterprise/v2 v2.14.2/go.mod h1:MwPgdgvBkE46aWuuXeBTCB8hQJ88p+CpXInROZYCTkc= +cloud.google.com/go/recaptchaenterprise/v2 v2.14.3 h1:qnU+urA6SZlRErosscaJ2DLG4264D6V8S4OgC3RU6QY= +cloud.google.com/go/recaptchaenterprise/v2 v2.14.3/go.mod h1:MiSHAXwja4btHPJFNJrDke//V+x83/ckXcdwbzn4+e8= cloud.google.com/go/recommendationengine v0.8.5 h1:ineqLswaCSBY0csYv5/wuXJMBlxATK6Xc5jJkpiTEdM= cloud.google.com/go/recommendationengine v0.8.11 h1:STJYdA/e/MAh2ZSdjss5YE/d0t0nt0WotBF9V0pgpPQ= cloud.google.com/go/recommendationengine v0.8.11/go.mod h1:cEkU4tCXAF88a4boMFZym7U7uyxvVwcQtKzS85IbQio= +cloud.google.com/go/recommendationengine v0.8.12 h1:X587hwzHqvmKyTR4EzH/QVYtvaCNqeIKhX9QC2iAw4g= +cloud.google.com/go/recommendationengine v0.8.12/go.mod h1:A3c39mOVC4utWlwk+MpchvkZTM6MSJXm3KUwTQ47VzA= cloud.google.com/go/recommender v1.12.1 h1:LVLYS3r3u0MSCxQSDUtLSkporEGi9OAE6hGvayrZNPs= cloud.google.com/go/recommender v1.12.7 h1:asEAoj4a3inPCdH8nbPaZDJWhR/xwfKi4tuSmIlaS2I= cloud.google.com/go/recommender v1.12.7/go.mod h1:lG8DVtczLltWuaCv4IVpNphONZTzaCC9KdxLYeZM5G4= +cloud.google.com/go/recommender v1.12.8 h1:3d+XXbeVU9Mt0TW6La+BhVFyCT5M2F1nazhAYrtahfM= +cloud.google.com/go/recommender v1.12.8/go.mod h1:zoJL8kPJJotOoNU3D2fCXW33vhbyIPe0Sq7ObhYLnGM= cloud.google.com/go/redis v1.14.2 h1:QF0maEdVv0Fj/2roU8sX3NpiDBzP9ICYTO+5F32gQNo= cloud.google.com/go/redis v1.16.4 h1:9CO6EcuM9/CpgtcjG6JZV+GFw3oDrRfwLwmvwo/uM1o= cloud.google.com/go/redis v1.16.4/go.mod h1:unCVfLP5eFrVhGLDnb7IaSaWxuZ+7cBgwwBwbdG9m9w= +cloud.google.com/go/redis v1.16.5 h1:yqidSLL+AE6IPNnEkAK6ZlxXp5c3zrsTTCB1TrpO054= +cloud.google.com/go/redis v1.16.5/go.mod h1:cWn6WHSEnmVZh9lJ9AN/UwDTtvlcT+TTRGvNIckUbG0= cloud.google.com/go/resourcemanager v1.9.5 h1:AZWr1vWVDKGwfLsVhcN+vcwOz3xqqYxtmMa0aABCMms= cloud.google.com/go/resourcemanager v1.9.11 h1:N8CmqszjKNOgJnrQVsg+g8VWIEGgcwsD5rPiay9cMC4= cloud.google.com/go/resourcemanager v1.9.11/go.mod h1:SbNAbjVLoi2rt9G74bEYb3aw1iwvyWPOJMnij4SsmHA= +cloud.google.com/go/resourcemanager v1.9.12 h1:p++iHmmeq9iWTia8WhNmPvBhL7MZsglQpZAYlHCguBs= +cloud.google.com/go/resourcemanager v1.9.12/go.mod h1:unouv9x3+I+6kVeE10LGM3oJ8aQrUZganWnRchitbAM= cloud.google.com/go/resourcesettings v1.6.5 h1:BTr5MVykJwClASci/7Og4Qfx70aQ4n3epsNLj94ZYgw= cloud.google.com/go/resourcesettings v1.7.4 h1:1VwLfvJi8QtGrKPwuisGqr6gcgaCSR6A57wIvN+fqkM= cloud.google.com/go/resourcesettings v1.7.4/go.mod h1:seBdLuyeq+ol2u9G2+74GkSjQaxaBWF+vVb6mVzQFG0= +cloud.google.com/go/resourcesettings v1.7.5 h1:zRvaQBE1O7wuB/UtX7Lw119r/xGcPzaY1POGpoMEhEs= +cloud.google.com/go/resourcesettings v1.7.5/go.mod h1:voqqKzYIrnoAqFKV6xk2qhgTnxzfGCJNOuBnHJEzcNU= cloud.google.com/go/retail v1.16.0 h1:Fn1GuAua1c6crCGqfJ1qMxG1Xh10Tg/x5EUODEHMqkw= cloud.google.com/go/retail v1.17.4 h1:YJgpBwCarAPqzaJS8ycIhyn2sAQT1RhTJRiTVBjtJAI= cloud.google.com/go/retail v1.17.4/go.mod h1:oPkL1FzW7D+v/hX5alYIx52ro2FY/WPAviwR1kZZTMs= +cloud.google.com/go/retail v1.17.5 h1:seOuQ16gMSxxre//JZy7lEdAKWwHQJMLYBmSfifJ/VI= +cloud.google.com/go/retail v1.17.5/go.mod h1:DSWPessLdnuvRH+N2FY+j1twyKtpRDKp4Y88dm7VqBw= cloud.google.com/go/run v1.3.4 h1:m9WDA7DzTpczhZggwYlZcBWgCRb+kgSIisWn1sbw2rQ= cloud.google.com/go/run v1.4.0 h1:ai1rnbX92iPqWg9MrbDbebsxlUSAiOK6N9dEDDQeVA0= cloud.google.com/go/run v1.4.0/go.mod h1:4G9iHLjdOC+CQ0CzA0+6nLeR6NezVPmlj+GULmb0zE4= +cloud.google.com/go/run v1.4.1 h1:grsUhL/Dlp7z5z2A4Nxi1oxEyktBkyB8VuobO6fuILs= +cloud.google.com/go/run v1.4.1/go.mod h1:gaXIpytRDfrJjb3pz9PRG2q2KUaDDDV+Uvmq6QRZH20= cloud.google.com/go/scheduler v1.10.6 h1:5U8iXLoQ03qOB+ZXlAecU7fiE33+u3QiM9nh4cd0eTE= cloud.google.com/go/scheduler v1.10.12 h1:8BxDXoHCcsAe2fXsvFrkBbTxgl+5JBrIy1+/HRS0nxY= cloud.google.com/go/scheduler v1.10.12/go.mod h1:6DRtOddMWJ001HJ6MS148rtLSh/S2oqd2hQC3n5n9fQ= +cloud.google.com/go/scheduler v1.10.13 h1:KEM2/3r4NIn6eOIL1tAEN1Qrot8xqKYuW1QKEQ+GyFU= +cloud.google.com/go/scheduler v1.10.13/go.mod h1:lDJItkp2hNrCsHOBtVExCzjXBzK9WI3yKNg713/OU4s= cloud.google.com/go/secretmanager v1.11.5 h1:82fpF5vBBvu9XW4qj0FU2C6qVMtj1RM/XHwKXUEAfYY= cloud.google.com/go/secretmanager v1.13.5/go.mod h1:/OeZ88l5Z6nBVilV0SXgv6XJ243KP2aIhSWRMrbvDCQ= cloud.google.com/go/secretmanager v1.13.6 h1:0ZEl/LuoB4xQsjVfQt3Gi/dZfOv36n4JmdPrMargzYs= @@ -307,37 +477,57 @@ cloud.google.com/go/secretmanager v1.13.6/go.mod h1:x2ySyOrqv3WGFRFn2Xk10iHmNmvm cloud.google.com/go/security v1.15.5 h1:wTKJQ10j8EYgvE8Y+KhovxDRVDk2iv/OsxZ6GrLP3kE= cloud.google.com/go/security v1.17.4 h1:ERhxAa02mnMEIIAXvzje+qJ+yWniP6l5uOX+k9ELCaA= cloud.google.com/go/security v1.17.4/go.mod h1:KMuDJH+sEB3KTODd/tLJ7kZK+u2PQt+Cfu0oAxzIhgo= +cloud.google.com/go/security v1.17.5 h1:FzjVVdJKgfHmDt1gsecHehVewA0wLuruHvA1g4o5k4c= +cloud.google.com/go/security v1.17.5/go.mod h1:MA8w7SbQAQO9CQ9r0R7HR0F7g1AJoqx87SFLpapq3OU= cloud.google.com/go/securitycenter v1.24.4 h1:/5jjkZ+uGe8hZ7pvd7pO30VW/a+pT2MrrdgOqjyucKQ= cloud.google.com/go/securitycenter v1.33.1 h1:K+jfFUTum2jl//uWCN+QKkKXRgidxTyGfGTqXPyDvUY= cloud.google.com/go/securitycenter v1.33.1/go.mod h1:jeFisdYUWHr+ig72T4g0dnNCFhRwgwGoQV6GFuEwafw= +cloud.google.com/go/securitycenter v1.34.0 h1:rf1n9DviaHlkjqG/Acy61nsQxSGL4w8hIQoSraNNQBM= +cloud.google.com/go/securitycenter v1.34.0/go.mod h1:7esjYVxn7k0nm02CnLNueFWD40FH0eunhookSEUalSs= cloud.google.com/go/servicecontrol v1.11.1 h1:d0uV7Qegtfaa7Z2ClDzr9HJmnbJW7jn0WhZ7wOX6hLE= cloud.google.com/go/servicedirectory v1.11.4 h1:da7HFI1229kyzIyuVEzHXip0cw0d+E0s8mjQby0WN+k= cloud.google.com/go/servicedirectory v1.11.11 h1:8Ky2lY0CWJJIIlsc+rKTn6C3SqOuVEwT3brDC6TJCjk= cloud.google.com/go/servicedirectory v1.11.11/go.mod h1:pnynaftaj9LmRLIc6t3r7r7rdCZZKKxui/HaF/RqYfs= +cloud.google.com/go/servicedirectory v1.11.12 h1:KPlLc16HUiUp5/dGHF7KlBUEub13Ps76J91xCMBG+5U= +cloud.google.com/go/servicedirectory v1.11.12/go.mod h1:A0mXC1awKEK5alkG7p3hxaHtb5SSPqAdeWx09RTIOGY= cloud.google.com/go/servicemanagement v1.8.0 h1:fopAQI/IAzlxnVeiKn/8WiV6zKndjFkvi+gzu+NjywY= cloud.google.com/go/serviceusage v1.6.0 h1:rXyq+0+RSIm3HFypctp7WoXxIA563rn206CfMWdqXX4= cloud.google.com/go/shell v1.7.5 h1:3Fq2hzO0ZSyaqBboJrFkwwf/qMufDtqwwA6ep8EZxEI= cloud.google.com/go/shell v1.7.11 h1:RobTXyL33DQITYQh//KJ9GjS4bsdj4fGmm2rkb/ywzM= cloud.google.com/go/shell v1.7.11/go.mod h1:SywZHWac7onifaT9m9MmegYp3GgCLm+tgk+w2lXK8vg= +cloud.google.com/go/shell v1.7.12 h1:UCDVhq9IkB1RWhUIJxj9Xr/c+BVVxMSAnnJUGjPfk4U= +cloud.google.com/go/shell v1.7.12/go.mod h1:QxxwQMvXqDUTYgMwbO7Y2Z6rojGzA7q64aQTCEj7xfM= cloud.google.com/go/spanner v1.57.0 h1:fJq+ZfQUDHE+cy1li0bJA8+sy2oiSGhuGqN5nqVaZdU= cloud.google.com/go/spanner v1.65.0 h1:XK15cs9lFFQo5n4Wh9nfrcPXAxWln6NdodDiQKmoD08= cloud.google.com/go/spanner v1.65.0/go.mod h1:dQGB+w5a67gtyE3qSKPPxzniedrnAmV6tewQeBY7Hxs= +cloud.google.com/go/spanner v1.67.0 h1:h8xfobxh5lQu4qJVMPH+wSiyU+ZM6ZTxRNqGeu9iIVA= +cloud.google.com/go/spanner v1.67.0/go.mod h1:Um+TNmxfcCHqNCKid4rmAMvoe/Iu1vdz6UfxJ9GPxRQ= cloud.google.com/go/speech v1.21.1 h1:nuFc+Kj5B8de75nN4FdPyUbI2SiBoHZG6BLurXL56Q0= cloud.google.com/go/speech v1.24.0 h1:3j+WpeBY57C0FDJxg317vpKgOLjL/kNxlcNPGSqXkqE= cloud.google.com/go/speech v1.24.0/go.mod h1:HcVyIh5jRXM5zDMcbFCW+DF2uK/MSGN6Rastt6bj1ic= +cloud.google.com/go/speech v1.24.1 h1:sgJ+sBzamry/ZBhbIZX6Dmv/BnrTAvWLXeJT1bmugnU= +cloud.google.com/go/speech v1.24.1/go.mod h1:th/IKNidPLzrbaEiKLIhTv/oTGADe4r4bzxZvYG62EE= cloud.google.com/go/storage v1.41.0/go.mod h1:J1WCa/Z2FcgdEDuPUY8DxT5I+d9mFKsCepp5vR6Sq80= cloud.google.com/go/storagetransfer v1.10.4 h1:dy4fL3wO0VABvzM05ycMUPFHxTPbJz9Em8ikAJVqSbI= cloud.google.com/go/storagetransfer v1.10.10 h1:GfxaYqX+kwlrSrJAENNmRTCGmSTgvouvS3XhgwKpOT8= cloud.google.com/go/storagetransfer v1.10.10/go.mod h1:8+nX+WgQ2ZJJnK8e+RbK/zCXk8T7HdwyQAJeY7cEcm0= +cloud.google.com/go/storagetransfer v1.10.11 h1:AF5iHhnbiVC4BEKf1b8ujWeUuXCfpRzO9aclF2j2A1w= +cloud.google.com/go/storagetransfer v1.10.11/go.mod h1:AMAR/PTS5yKPp1FHP6rk3eJYGmHF14vQYiHddcIgoOA= cloud.google.com/go/talent v1.6.6 h1:JssV0CE3FNujuSWn7SkosOzg7qrMxVnt6txOfGcMSa4= cloud.google.com/go/talent v1.6.12 h1:JN721EjG+UTfHVVaMhyxwKCCJPjUc8PiS0RnW/7kWfE= cloud.google.com/go/talent v1.6.12/go.mod h1:nT9kNVuJhZX2QgqKZS6t6eCWZs5XEBYRBv6bIMnPmo4= +cloud.google.com/go/talent v1.6.13 h1:DLrLO6LVl6T7v07Jc3+4IaI+sDFRbgd7MTEbTow5qVE= +cloud.google.com/go/talent v1.6.13/go.mod h1:jqjQzIF7ZPCxFSdsfhgUF0wGB+mbytYzyUqaHLiQcQg= cloud.google.com/go/texttospeech v1.7.5 h1:dxY2Q5mHCbrGa3oPR2O3PCicdnvKa1JmwGQK36EFLOw= cloud.google.com/go/texttospeech v1.7.11 h1:jzko1ahItjLYEWr6n3lTIoBSinD1JzavEuDzYLWZNko= cloud.google.com/go/texttospeech v1.7.11/go.mod h1:Ua125HU+WT2IkIo5MzQtuNpNEk72soShJQVdorZ1SAE= +cloud.google.com/go/texttospeech v1.7.12 h1:W33C7hjh61V1HVAh4E1RqAx2hSPIebmilYqMuqvP/HQ= +cloud.google.com/go/texttospeech v1.7.12/go.mod h1:B1Xck47Mhy/PJMnvrLkv0gfKGinGP78c0XFZjWB7TdY= cloud.google.com/go/tpu v1.6.5 h1:C8YyYda8WtNdBoCgFwwBzZd+S6+EScHOxM/z1h0NNp8= cloud.google.com/go/tpu v1.6.11 h1:uMrwnK05cocNt3OOp+mZ16xlvIKaXUt3QUXkUbG4LdM= cloud.google.com/go/tpu v1.6.11/go.mod h1:W0C4xaSj1Ay3VX/H96FRvLt2HDs0CgdRPVI4e7PoCDk= +cloud.google.com/go/tpu v1.6.12 h1:n54G/s4O6t2sbTiTkhj795JW6iCBSzI1ccrXp+GAP6c= +cloud.google.com/go/tpu v1.6.12/go.mod h1:IFJa2vI7gxF6fypOQXYmbuFwKLsde4zVwcv1p9zhOqY= cloud.google.com/go/trace v1.10.5 h1:0pr4lIKJ5XZFYD9GtxXEWr0KkVeigc3wlGpZco0X1oA= cloud.google.com/go/trace v1.10.11/go.mod h1:fUr5L3wSXerNfT0f1bBg08W4axS2VbHGgYcfH4KuTXU= cloud.google.com/go/trace v1.10.12 h1:GoGZv1iAXEa73HgSGNjRl2vKqp5/f2AeKqErRFXA2kg= @@ -346,34 +536,54 @@ cloud.google.com/go/translate v1.10.1 h1:upovZ0wRMdzZvXnu+RPam41B0mRJ+coRXFP2cYF cloud.google.com/go/translate v1.10.3/go.mod h1:GW0vC1qvPtd3pgtypCv4k4U8B7EdgK9/QEF2aJEUovs= cloud.google.com/go/translate v1.10.7 h1:W16MpZ2Z3TWoHbNHmyHz9As276lGVTSwxRcquv454R0= cloud.google.com/go/translate v1.10.7/go.mod h1:mH/+8tvcItuy1cOWqU+/Y3iFHgkVUObNIQYI/kiFFiY= +cloud.google.com/go/translate v1.11.0 h1:ncOb+dtBr65+5Ay9VotOA8j5RlrUJXB+qdq+xqpV4Ls= +cloud.google.com/go/translate v1.11.0/go.mod h1:UFNHzrfcEo/ZCmA5SveVqxh0l57BP27HCvroN5o59FI= cloud.google.com/go/video v1.20.4 h1:TXwotxkShP1OqgKsbd+b8N5hrIHavSyLGvYnLGCZ7xc= cloud.google.com/go/video v1.22.0 h1:+FTZi7NtT4FV2Y1j3zC3zYjaRrlGqKsZpbLweredEWM= cloud.google.com/go/video v1.22.0/go.mod h1:CxPshUNAb1ucnzbtruEHlAal9XY+SPG2cFqC/woJzII= +cloud.google.com/go/video v1.22.1 h1:G2gFE34k6TIC0CHW1OTbF6tKfzA3X+MbjkoLblu0vWU= +cloud.google.com/go/video v1.22.1/go.mod h1:+AYF4e9kqQhra0AfKPoOOIUK0Ho7BquOWQK+Te+Qnns= cloud.google.com/go/videointelligence v1.11.5 h1:mYaWH8uhUCXLJCN3gdXswKzRa2+lK0zN6/KsIubm6pE= cloud.google.com/go/videointelligence v1.11.11 h1:zl8xijOEavernn/t6mZZ4fg0pIVc2yquHH73oj0Leo4= cloud.google.com/go/videointelligence v1.11.11/go.mod h1:dab2Ca3AXT6vNJmt3/6ieuquYRckpsActDekLcsd6dU= +cloud.google.com/go/videointelligence v1.11.12 h1:dFCXde/zOkP1yhM8aCuFVC+smix46sP2U56OywCOkAQ= +cloud.google.com/go/videointelligence v1.11.12/go.mod h1:dQlDAFtTwsZi3UI+03NVF4XQoarx0VU5/IKMLyVyC2E= cloud.google.com/go/vision v1.2.0 h1:/CsSTkbmO9HC8iQpxbK8ATms3OQaX3YQUeTMGCxlaK4= cloud.google.com/go/vision/v2 v2.8.0 h1:W52z1b6LdGI66MVhE70g/NFty9zCYYcjdKuycqmlhtg= cloud.google.com/go/vision/v2 v2.8.6 h1:HyFEUXQa0SvlF0LASCn/x+juNCH4kIXQrUqi6SIcYvE= cloud.google.com/go/vision/v2 v2.8.6/go.mod h1:G3v0uovxCye3u369JfrHGY43H6u/IQ08x9dw5aVH8yY= +cloud.google.com/go/vision/v2 v2.8.7 h1:4hWiRo2j4zzmCzXG+SkJVYq0dvR6TklFHkxdsmdfMsU= +cloud.google.com/go/vision/v2 v2.8.7/go.mod h1:4ADQGbgAAvEDn/2I6XLeBN6mCUq6D44bfjWaqQc6iYU= cloud.google.com/go/vmmigration v1.7.5 h1:5v9RT2vWyuw3pK2ox0HQpkoftO7Q7/8591dTxxQc79g= cloud.google.com/go/vmmigration v1.7.11 h1:yqwkTPpvSw9dUfnl9/APAVrwO9UW1jJZtgbZpNQ+WdU= cloud.google.com/go/vmmigration v1.7.11/go.mod h1:PmD1fDB0TEHGQR1tDZt9GEXFB9mnKKalLcTVRJKzcQA= +cloud.google.com/go/vmmigration v1.7.12 h1:+X5l9sfrevUi5EeOM7LhzFFzGVT/N7u0TJY7jdIiIQA= +cloud.google.com/go/vmmigration v1.7.12/go.mod h1:Fb6yZsMdgFUo3wdDc7vK75KmBzXkY1Tio/053vuvCXU= cloud.google.com/go/vmwareengine v1.1.1 h1:EGdDi9QbqThfZq3ILcDK5g+m9jTevc34AY5tACx5v7k= cloud.google.com/go/vmwareengine v1.2.0 h1:9Fjn/RoeOMo8UQt1TbXmmw7rJApC26BqnISAI1AERcc= cloud.google.com/go/vmwareengine v1.2.0/go.mod h1:rPjCHu6hG9N8d6PhkoDWFkqL9xpbFY+ueVW+0pNFbZg= +cloud.google.com/go/vmwareengine v1.2.1 h1:UChEIPaM3wxBXKLy7Ooqeey3YNesta7PR5D2h7lI61I= +cloud.google.com/go/vmwareengine v1.2.1/go.mod h1:OE5z8qJdTiPpSeWunFenN/RMF7ymRgI0HvJ/c7Zl5U0= cloud.google.com/go/vpcaccess v1.7.5 h1:XyL6hTLtEM/eE4F1GEge8xUN9ZCkiVWn44K/YA7z1rQ= cloud.google.com/go/vpcaccess v1.7.11 h1:1XgRP+Q2X6MvE/xnexpQ7ydgav+IO5UcKUIJEbL65J8= cloud.google.com/go/vpcaccess v1.7.11/go.mod h1:a2cuAiSCI4TVK0Dt6/dRjf22qQvfY+podxst2VvAkcI= +cloud.google.com/go/vpcaccess v1.7.12 h1:n077TcPH7S8RjZGBwHWykVfoVaa41O5VK9xn8KR18+0= +cloud.google.com/go/vpcaccess v1.7.12/go.mod h1:Bt9j9aqlNDj1xW5uMNrHyhpc61JZgttbQRecG9xm1cE= cloud.google.com/go/webrisk v1.9.5 h1:251MvGuC8wisNN7+jqu9DDDZAi38KiMXxOpA/EWy4dE= cloud.google.com/go/webrisk v1.9.11 h1:2qwEqnXrToIv2Y4xvsUSxCk7R2Ki+3W2+GNyrytoKTQ= cloud.google.com/go/webrisk v1.9.11/go.mod h1:mK6M8KEO0ZI7VkrjCq3Tjzw4vYq+3c4DzlMUDVaiswE= +cloud.google.com/go/webrisk v1.9.12 h1:2WWCTU5744V0AsZomJxzH18LG7jlL13z1iDzgMWAJOQ= +cloud.google.com/go/webrisk v1.9.12/go.mod h1:YaAgE2xKzIN8yQNUspTTeZbvdcifSJh+wcMyXmp8fgg= cloud.google.com/go/websecurityscanner v1.6.5 h1:YqWZrZYabG88TZt7364XWRJGhxmxhony2ZUyZEYMF2k= cloud.google.com/go/websecurityscanner v1.6.11 h1:r3ePI3YN7ujwX8c9gIkgbVjYVwP4yQA4X2z6P7+HNxI= cloud.google.com/go/websecurityscanner v1.6.11/go.mod h1:vhAZjksELSg58EZfUQ1BMExD+hxqpn0G0DuyCZQjiTg= +cloud.google.com/go/websecurityscanner v1.6.12 h1:0RJvr/1Eybjt6klGMrW4U5DVitv1P+BoLmrRU6Xmzc0= +cloud.google.com/go/websecurityscanner v1.6.12/go.mod h1:9WFCBNpS0EIIhQaqiNC3ezZ48qisGPh3Ekz6T2n9Ioc= cloud.google.com/go/workflows v1.12.4 h1:uHNmUiatTbPQ4H1pabwfzpfEYD4BBnqDHqMm2IesOh4= cloud.google.com/go/workflows v1.12.10 h1:EGJeZmwgE71jxFOI5s9iKST2Bivif3DSzlqVbiXACXQ= cloud.google.com/go/workflows v1.12.10/go.mod h1:RcKqCiOmKs8wFUEf3EwWZPH5eHc7Oq0kamIyOUCk0IE= +cloud.google.com/go/workflows v1.12.11 h1:9pfL+XeaaNDEPTc02VvX70qW36cBrTHmcH1plZwOI7s= +cloud.google.com/go/workflows v1.12.11/go.mod h1:0cYsbMDyqr/1SbEt1DfN+S+mI2AAnVrT7+Hrh7qaxZ0= code.cloudfoundry.org/clock v1.1.0 h1:XLzC6W3Ah/Y7ht1rmZ6+QfPdt1iGWEAAtIZXgiaj57c= code.cloudfoundry.org/clock v1.1.0/go.mod h1:yA3fxddT9RINQL2XHS7PS+OXxKCGhfrZmlNUCIM6AKo= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9 h1:yxE46rQA0QaqPGqN2UnwXvgCrRqtjR1CsGSWVTRjvv4= @@ -390,9 +600,22 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUu docker.io/go-docker v1.0.0 h1:VdXS/aNYQxyA9wdLD5z8Q8Ro688/hG8HzKxYVEVbE6s= docker.io/go-docker v1.0.0/go.mod h1:7tiAn5a0LFmjbPDbyTPOaTTOuG1ZRNXdPA6RvKY+fpY= gioui.org v0.0.0-20210308172011-57750fc8a0a6 h1:K72hopUosKG3ntOPNG4OzzbuhxGuVf06fa2la1/H/Ho= +gioui.org v0.2.0 h1:RbzDn1h/pCVf/q44ImQSa/J3MIFpY3OWphzT/Tyei+w= +gioui.org v0.2.0/go.mod h1:1H72sKEk/fNFV+l0JNeM2Dt3co3Y4uaQcD+I+/GQ0e4= +gioui.org/cpu v0.0.0-20220412190645-f1e9e8c3b1f7 h1:tNJdnP5CgM39PRc+KWmBRRYX/zJ+rd5XaYxY5d5veqA= +gioui.org/cpu v0.0.0-20220412190645-f1e9e8c3b1f7/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= +gioui.org/shader v1.0.6 h1:cvZmU+eODFR2545X+/8XucgZdTtEjR3QWW6W65b0q5Y= +gioui.org/shader v1.0.6/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM= +gioui.org/x v0.2.0 h1:/MbdjKH19F16auv19UiQxli2n6BYPw7eyh9XBOTgmEw= +gioui.org/x v0.2.0/go.mod h1:rCGN2nZ8ZHqrtseJoQxCMZpt2xrZUrdZ2WuMRLBJmYs= +git.sr.ht/~sbinet/cmpimg v0.1.0 h1:E0zPRk2muWuCqSKSVZIWsgtU9pjsw3eKHi8VmQeScxo= +git.sr.ht/~sbinet/cmpimg v0.1.0/go.mod h1:FU12psLbF4TfNXkKH2ZZQ29crIqoiqTZmeQ7dkp/pxE= git.sr.ht/~sbinet/gg v0.3.1 h1:LNhjNn8DerC8f9DHLz6lS0YYul/b602DUxDgGkd/Aik= +git.sr.ht/~sbinet/gg v0.5.0 h1:6V43j30HM623V329xA9Ntq+WJrMjDxRjuAB1LFWF5m8= +git.sr.ht/~sbinet/gg v0.5.0/go.mod h1:G2C0eRESqlKhS7ErsNey6HHrqU1PwsnCQlekFi9Q2Oo= github.com/99designs/basicauth-go v0.0.0-20160802081356-2a93ba0f464d h1:j6oB/WPCigdOkxtuPl1VSIiLpy7Mdsu6phQffbF19Ng= github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e h1:rl2Aq4ZODqTDkeSqQBy+fzpZPamacO1Srp8zq7jf2Sc= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4= github.com/Azure/azure-amqp-common-go/v3 v3.2.2 h1:CJpxNAGxP7UBhDusRUoaOn0uOorQyAYhQYLnNgkRhlY= github.com/Azure/azure-amqp-common-go/v3 v3.2.3 h1:uDF62mbd9bypXWi19V1bN5NZEO84JqgmI5G73ibAmrk= github.com/Azure/azure-amqp-common-go/v3 v3.2.3/go.mod h1:7rPmbSfszeovxGfc5fSAXE4ehlXQZHpMja2OtxC2Tas= @@ -431,7 +654,7 @@ github.com/ClickHouse/ch-go v0.58.2/go.mod h1:Ap/0bEmiLa14gYjCiRkYGbXvbe8vwdrfTY github.com/ClickHouse/clickhouse-go/v2 v2.17.1 h1:ZCmAYWpu75IyEi7+Yrs/uaAjiCGY5wfW5kXo64exkX4= github.com/ClickHouse/clickhouse-go/v2 v2.17.1/go.mod h1:rkGTvFDTLqLIm0ma+13xmcCfr/08Gvs7KmFt1tgiWHQ= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0 h1:1PwO5w5VCtlUUl+KTOBsTGZlhjWkcybsGaAau52tOy8= github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= @@ -443,10 +666,10 @@ github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0/go.mod h1:dppbR7CwXD4p github.com/IBM/sarama v1.40.1/go.mod h1:+5OFwA5Du9I6QrznhaMHsuwWdWZNMjaBSIxEWEgKOYE= github.com/IBM/sarama v1.43.0 h1:YFFDn8mMI2QL0wOrG0J2sFoVIAFl7hS9JQi2YZsXtJc= github.com/IBM/sarama v1.43.0/go.mod h1:zlE6HEbC/SMQ9mhEYaF7nNLYOUyrs0obySKCckWP9BM= +github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= github.com/KimMachineGun/automemlimit v0.6.0 h1:p/BXkH+K40Hax+PuWWPQ478hPjsp9h1CPDhLlA3Z37E= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o= github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= @@ -468,6 +691,7 @@ github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrd github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9 h1:7kQgkwGRoLzC9K0oyXdJo7nve/bynv/KwUsxbiTlzAM= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19 h1:iXUgAaqDcIUGbRoy2TdeofRG/j1zpGRSEmNK05T+bi8= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= @@ -487,6 +711,8 @@ github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= +github.com/andybalholm/stroke v0.0.0-20221221101821-bd29b49d73f0 h1:uF5Q/hWnDU1XZeT6CsrRSxHLroUSEYYO3kgES+yd+So= +github.com/andybalholm/stroke v0.0.0-20221221101821-bd29b49d73f0/go.mod h1:ccdDYaY5+gO+cbnQdFxEXqfy0RkoV25H3jLXUDNM3wg= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= @@ -524,18 +750,23 @@ github.com/aws/aws-sdk-go-v2/service/ssm v1.52.4 h1:hgSBvRT7JEWx2+vEGI9/Ld5rZtl7 github.com/aws/aws-sdk-go-v2/service/ssm v1.52.4/go.mod h1:v7NIzEFIHBiicOMaMTuEmbnzGnqW0d+6ulNALul6fYE= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible h1:Ppm0npCCsmuR9oQaBtRuZcmILVE74aXE+AmrJj8L2ns= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/bradleyjkemp/cupaloy/v2 v2.6.0 h1:knToPYa2xtfg42U3I6punFEjaGFKWQRXJwj0JTv4mTs= github.com/bradleyjkemp/cupaloy/v2 v2.6.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/brianvoe/gofakeit/v6 v6.25.0 h1:ZpFjktOpLZUeF8q223o0rUuXtA+m5qW5srjvVi+JkXk= github.com/brianvoe/gofakeit/v6 v6.25.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= +github.com/bufbuild/protocompile v0.10.0/go.mod h1:G9qQIQo0xZ6Uyj6CMNz0saGmx2so+KONo8/KrELABiY= github.com/bufbuild/protovalidate-go v0.2.1 h1:pJr07sYhliyfj/STAM7hU4J3FKpVeLVKvOBmOTN8j+s= github.com/bufbuild/protovalidate-go v0.2.1/go.mod h1:e7XXDtlxj5vlEyAgsrxpzayp4cEMKCSSb8ZCkin+MVA= github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0= github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= +github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= +github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/casbin/casbin/v2 v2.37.0 h1:/poEwPSovi4bTOcP752/CsTQiRz2xycyVKFG7GUhbDw= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= @@ -544,6 +775,7 @@ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/chromedp/cdproto v0.0.0-20220208224320-6efb837e6bc2/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U= github.com/chromedp/chromedp v0.9.2 h1:dKtNz4kApb06KuSXoTQIyUC2TrA0fhGDwNZf3bcgfKw= github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= @@ -559,7 +791,9 @@ github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nC github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c h1:2zRrJWIt/f9c9HhNHAgrRgq0San5gRRUJTBXLkchal0= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= +github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= @@ -594,15 +828,21 @@ github.com/dave/patsy v0.0.0-20210517141501-957256f50cba h1:1o36L4EKbZzazMk8iGC4 github.com/dave/rebecca v0.9.1 h1:jxVfdOxRirbXL28vXMvUvJ1in3djwkVKXCq339qhBL0= github.com/dchest/uniuri v1.2.0 h1:koIcOUdrTIivZgSLhHQvKgqdWZq5d7KdMEWF1Ud6+5g= github.com/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY= +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 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA= github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= github.com/devigned/tab v0.1.1 h1:3mD6Kb1mUOYeLpJvTVSDwSg5ZsfSxfvxGRTxRsJsITA= +github.com/dgraph-io/badger v1.6.0 h1:DshxFxZWXUcO0xX476VJC07Xsr6ZCBVRHKZ93Oh7Evo= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dhui/dktest v0.3.0 h1:kwX5a7EkLcjo7VpsPQSYJcKGbXBXdjI9FGjuUj1jn6I= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= github.com/drone/drone-runtime v1.1.0 h1:IsKbwiLY6+ViNBzX0F8PERJVZZcEJm9rgxEh3uZP5IE= github.com/drone/drone-runtime v1.1.0/go.mod h1:+osgwGADc/nyl40J0fdsf8Z09bgcBZXvXXnLOY48zYs= github.com/drone/drone-yaml v1.2.3 h1:SWzLmzr8ARhbtw1WsVDENa8WFY2Pi9l0FVMfafVUWz8= @@ -617,15 +857,22 @@ github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6/go.mod h1 github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= github.com/elastic/go-sysinfo v1.11.2 h1:mcm4OSYVMyws6+n2HIVMGkln5HOpo5Ie1ZmbbNn0jg4= github.com/elastic/go-sysinfo v1.11.2/go.mod h1:GKqR8bbMK/1ITnez9NIsIfXQr25aLhRJa7AfT8HpBFQ= github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0= github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= +github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155 h1:IgJPqnrlY2Mr4pYB6oaMKvFvwJ9H+X6CCY5x1vCTcpc= +github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155/go.mod h1:5Wkq+JduFtdAXihLmeTJf+tRYIT4KBc2vPXDhwVo1pA= +github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/expr-lang/expr v1.16.2 h1:JvMnzUs3LeVHBvGFcXYmXo+Q6DPDmzrlcSBO6Wy3w4s= github.com/expr-lang/expr v1.16.2/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 h1:DddqAaWDpywytcG8w/qoQ5sAN8X12d3Z3koB0C3Rxsc= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= +github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= @@ -637,19 +884,30 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/fsouza/fake-gcs-server v1.7.0 h1:Un0BXUXrRWYSmYyC1Rqm2e2WJfTPyDy/HGMz31emTi8= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8= +github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= github.com/go-faster/errors v0.6.1 h1:nNIPOBkprlKzkThvS/0YaX8Zs9KewLCOSFQS5BU06FI= github.com/go-faster/errors v0.6.1/go.mod h1:5MGV2/2T9yvlrbhe9pD9LO5Z/2zCSq2T8j+Jpi2LAyY= github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ= +github.com/go-fonts/dejavu v0.3.2 h1:3XlHi0JBYX+Cp8n98c6qSoHrxPa4AUKDMKdrh/0sUdk= +github.com/go-fonts/dejavu v0.3.2/go.mod h1:m+TzKY7ZEl09/a17t1593E4VYW8L1VaBXHzFZOIjGEY= github.com/go-fonts/latin-modern v0.2.0 h1:5/Tv1Ek/QCr20C6ZOz15vw3g7GELYL98KWr8Hgo+3vk= +github.com/go-fonts/latin-modern v0.3.2 h1:M+Sq24Dp0ZRPf3TctPnG1MZxRblqyWC/cRUL9WmdaFc= +github.com/go-fonts/latin-modern v0.3.2/go.mod h1:9odJt4NbRrbdj4UAMuLVd4zEukf6aAEKnDaQga0whqQ= github.com/go-fonts/liberation v0.3.0 h1:3BI2iaE7R/s6uUUtzNCjo3QijJu3aS4wmrMgfSpYQ+8= github.com/go-fonts/liberation v0.3.0/go.mod h1:jdJ+cqF+F4SUL2V+qxBth8fvBpBDS7yloUL5Fi8GTGY= +github.com/go-fonts/liberation v0.3.2 h1:XuwG0vGHFBPRRI8Qwbi5tIvR3cku9LUfZGq/Ar16wlQ= +github.com/go-fonts/liberation v0.3.2/go.mod h1:N0QsDLVUQPy3UYg9XAc3Uh3UDMp2Z7M1o4+X98dXkmI= github.com/go-fonts/stix v0.1.0 h1:UlZlgrvvmT/58o573ot7NFw0vZasZ5I6bcIft/oMdgg= +github.com/go-fonts/stix v0.2.2 h1:v9krocr13J1llaOHLEol1eaHsv8S43UuFX/1bFgEJJ4= +github.com/go-fonts/stix v0.2.2/go.mod h1:SUxggC9dxd/Q+rb5PkJuvfvTbOPtNc2Qaua00fIp9iU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo= @@ -657,8 +915,14 @@ github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= github.com/go-latex/latex v0.0.0-20230307184459-12ec69307ad9 h1:NxXI5pTAtpEaU49bpLpQoDsu1zrteW/vxzTz8Cd2UAs= github.com/go-latex/latex v0.0.0-20230307184459-12ec69307ad9/go.mod h1:gWuR/CrFDDeVRFQwHPvsv9soJVB/iqymhuZQuJ3a9OM= +github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea h1:DfZQkvEbdmOe+JK2TMtBM+0I9GSdzE2y/L1/AmD8xKc= +github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea/go.mod h1:Y7Vld91/HRbTBm7JwoI7HejdDB0u+e9AUBO9MB7yuZk= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8= +github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= +github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -666,6 +930,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-text/typesetting v0.0.0-20230803102845-24e03d8b5372 h1:FQivqchis6bE2/9uF70M2gmmLpe82esEm2QadL0TEJo= +github.com/go-text/typesetting v0.0.0-20230803102845-24e03d8b5372/go.mod h1:evDBbvNR/KaVFZ2ZlDSOWWXIUKq0wCOEtzLxRM8SG3k= github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c= github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= @@ -676,10 +942,12 @@ github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198/go.mod h1:DTh/Y2+Nbn github.com/goccy/go-yaml v1.11.0 h1:n7Z+zx8S9f9KgzG6KtQKf+kwqXZlLNR2F6018Dgau54= github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4 h1:vF83LI8tAakwEwvWZtrIEx7pOySacl2TOxx6eXk4ePo= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +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/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws= @@ -711,8 +979,11 @@ github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grafadruid/go-druid v0.0.6 h1:Nt9jQrhrtHi1BJICN9aDJgYDmBmc10pJYpQiuwAsxa4= +github.com/grafadruid/go-druid v0.0.6/go.mod h1:KY3a6MrVMKkXgMTwBS9Nrhm1E8OWyR4gd0WzUi8d/zM= github.com/grafana/authlib v0.0.0-20240730122259-a0d13672efb1/go.mod h1:YA9We4kTafu7mlMnUh3In6Q2wpg8fYN3ycgCKOK1TB8= github.com/grafana/authlib/claims v0.0.0-20240809101159-74eaccc31a06/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= +github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/gomemcache v0.0.0-20240229205252-cd6a66d6fb56/go.mod h1:PGk3RjYHpxMM8HFPhKKo+vve3DdlPUELZLSDEFehPuU= github.com/grafana/grafana-plugin-sdk-go v0.235.0/go.mod h1:6n9LbrjGL3xAATntYVNcIi90G9BVHRJjzHKz5FXVfWw= github.com/grafana/prometheus-alertmanager v0.25.1-0.20240422145632-c33c6b5b6e6b h1:HCbWyVL6vi7gxyO76gQksSPH203oBJ1MJ3JcG1OQlsg= @@ -748,10 +1019,17 @@ github.com/hashicorp/serf v0.10.0/go.mod h1:bXN03oZc5xlH46k/K1qTrpXb9ERKyY1/i/N5 github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hudl/fargo v1.4.0 h1:ZDDILMbB37UlAVLlWcJ2Iz1XuahZZTDZfdCKeclfq2s= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91 h1:KyZDvZ/GGn+r+Y3DKZ7UOQ/TP4xV6HNkrwiVMB1GnNY= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 h1:KwWnWVWCNtNq/ewIX7HIKnELmEx2nDP42yskD/pi7QE= +github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= github.com/influxdata/influxdb v1.7.6 h1:8mQ7A/V+3noMGCt/P9pD09ISaiz9XvgCk303UYA3gcs= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig= +github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/iris-contrib/blackfriday v2.0.0+incompatible h1:o5sHQHHm0ToHUlAJSTjW9UWicjJSDDauOOQ2AHuIVp4= +github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE= +github.com/iris-contrib/jade v1.1.3 h1:p7J/50I0cjo0wq/VWVCDFd8taPJbuFC+bq23SniRFX0= +github.com/iris-contrib/pongo2 v0.0.1 h1:zGP7pW51oi5eQZMIlGA3I+FHY9/HOQWDB+572yin0to= github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= @@ -800,6 +1078,7 @@ github.com/jsternberg/zap-logfmt v1.2.0/go.mod h1:kz+1CUmCutPWABnNkOu9hOHKdT2q3T github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d h1:c93kUJDtVAXFEhsCh5jSxyOJmFHuzcihnslQiX8Urwo= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5 h1:PJr+ZMXIecYc1Ey2zucXdR73SMBtgjPgwa31099IMv0= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= @@ -807,6 +1086,7 @@ github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= +github.com/kataras/neffos v0.0.14 h1:pdJaTvUG3NQfeMbbVCI8JT2T5goPldyyfUB2PJfh1Bs= github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= @@ -857,8 +1137,10 @@ github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqA github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= github.com/matryer/moq v0.3.3 h1:pScMH9VyrdT4S93yiLpVyU8rCDqGQr24uOyBxmktG5Q= github.com/matryer/moq v0.3.3/go.mod h1:RJ75ZZZD71hejp39j4crZLsEDszGk6iH4v4YsWFKH4s= +github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= +github.com/mediocregopher/radix/v3 v3.4.2 h1:galbPBjIwmyREgwGCfQEN4X8lxbJnKBYurgz+VfcStA= github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= github.com/microsoft/ApplicationInsights-Go v0.4.4 h1:G4+H9WNs6ygSCe6sUyxRc2U81TI5Es90b2t/MwX5KqY= @@ -877,6 +1159,7 @@ github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5 h1:8Q0qkMVC/MmWkpI github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU= github.com/mostynb/go-grpc-compression v1.2.2 h1:XaDbnRvt2+1vgr0b/l0qh4mJAfIxE0bKXtz2Znl3GGI= github.com/mostynb/go-grpc-compression v1.2.2/go.mod h1:GOCr2KBxXcblCuczg3YdLQlcin1/NfyDA348ckuCH6w= +github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs= github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8 h1:P48LjvUQpTReR3TQRbxSeSBsMXzfK0uol7eRcr7VBYQ= github.com/natessilva/dag v0.0.0-20180124060714-7194b8dcc5c4 h1:dnMxwus89s86tI8rcGVp2HwZzlz7c5o92VOy7dSckBQ= github.com/nats-io/jwt v1.2.2 h1:w3GMTO969dFg+UOKTmmyuu7IGdusK+7Ytlt//OYH/uU= @@ -964,8 +1247,12 @@ github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwy github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/profile v1.2.1 h1:F++O52m40owAmADcojzM+9gyjmMOY/T4oYJkgFDH8RE= +github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= +github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= @@ -996,7 +1283,6 @@ github.com/sagikazarmark/crypt v0.17.0/go.mod h1:SMtHTvdmsZMuY/bpZoqokSoChIrcJ/e github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e h1:uO75wNGioszjmIzcY/tvdDYKRLVvzggtAmmJkn9j4GQ= github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e/go.mod h1:tm/wZFQ8e24NYaBGIlnO2WGCAi67re4HHuOm0sftE/M= github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY= @@ -1006,8 +1292,11 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I github.com/sony/gobreaker v0.4.1 h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/speakeasy-api/openapi-overlay v0.9.0 h1:Wrz6NO02cNlLzx1fB093lBlYxSI54VRhy1aSutx0PQg= +github.com/speakeasy-api/openapi-overlay v0.9.0/go.mod h1:f5FloQrHA7MsxYg9djzMD5h6dxrHjVVByWKh7an8TRc= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stoewer/parquet-cli v0.0.7 h1:rhdZODIbyMS3twr4OM3am8BPPT5pbfMcHLH93whDM5o= github.com/stoewer/parquet-cli v0.0.7/go.mod h1:bskxHdj8q3H1EmfuCqjViFoeO3NEvs5lzZAQvI8Nfjk= github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= @@ -1034,8 +1323,11 @@ github.com/uber-go/atomic v1.4.0 h1:yOuPqEq4ovnhEjpHmfFwsqBXDYbQeT6Nb0bwD6XnD5o= github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= +github.com/valyala/fasthttp v1.6.0 h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= github.com/vburenin/ifacemaker v1.2.1 h1:3Vq8B/bfBgjWTkv+jDg4dVL1KHt3k1K4lO7XRxYA2sk= github.com/vertica/vertica-sql-go v1.3.3 h1:fL+FKEAEy5ONmsvya2WH5T8bhkvY27y/Ik3ReR2T+Qw= github.com/vertica/vertica-sql-go v1.3.3/go.mod h1:jnn2GFuv+O2Jcjktb7zyc4Utlbu9YVqpHH/lx63+1M4= @@ -1045,6 +1337,8 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX8Wdm2/JPA= @@ -1056,14 +1350,14 @@ github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= +github.com/yalue/merged_fs v1.2.2 h1:vXHTpJBluJryju7BBpytr3PDIkzsPMpiEknxVGPhN/I= +github.com/yalue/merged_fs v1.2.2/go.mod h1:WqqchfVYQyclV2tnR7wtRhBddzBvLVR83Cjw9BKQw0M= github.com/ydb-platform/ydb-go-genproto v0.0.0-20240126124512-dbb0e1720dbf h1:ckwNHVo4bv2tqNkgx3W3HANh3ta1j6TR5qw08J1A7Tw= github.com/ydb-platform/ydb-go-genproto v0.0.0-20240126124512-dbb0e1720dbf/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= github.com/ydb-platform/ydb-go-sdk/v3 v3.55.1 h1:Ebo6J5AMXgJ3A438ECYotA0aK7ETqjQx9WoZvVxzKBE= @@ -1189,8 +1483,15 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp/shiny v0.0.0-20230801115018-d63ba01acd4b h1:sgkbz1SFTsoQIvzTIw45hccUcGocu00QM3qucBYV8b0= +golang.org/x/exp/shiny v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:UH99kUObWAZkDnWqppdQe5ZhPYESUw8I0zVV1uWBR+0= golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4= golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0= +golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= +golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1203,7 +1504,6 @@ golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -1216,10 +1516,13 @@ golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/plot v0.10.1 h1:dnifSs43YJuNMDzB7v8wV64O4ABBHReuAVAoBxqBqS4= +gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE= +gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU= google.golang.org/api v0.166.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe/bSA= google.golang.org/api v0.177.0/go.mod h1:srbhue4MLjkjbkux5p3dw/ocYOSZTaIEvf7bCOnFQDw= google.golang.org/api v0.183.0/go.mod h1:q43adC5/pHoSZTx5h2mSmdF7NcyfW9JuDyIOJAgS9ZQ= @@ -1227,7 +1530,6 @@ google.golang.org/api v0.187.0/go.mod h1:KIHlTc4x7N7gKKuVsdmfBXN13yEEWXWFURWY6SB google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 h1:SeX3QUcBj3fciwnfPT9kt5gBhFy/FCZtYZ+I/RB8agc= google.golang.org/genproto v0.0.0-20240528184218-531527333157/go.mod h1:ubQlAQnzejB8uZzszhrTCU2Fyp6Vi7ZE5nn0c3W8+qQ= google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:s7iA721uChleev562UJO2OYB0PPT9CMFjV+Ce7VJH5M= google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= @@ -1238,13 +1540,18 @@ google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8/go. google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo= google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= google.golang.org/genproto/googleapis/api v0.0.0-20240722135656-d784300faade/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f/go.mod h1:AHT0dDg3SoMOgZGnZk29b5xTbPHMoEC8qthmBLJCpys= google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:OFMYQFHJ4TM3JRlWDZhJbZfra2uqc3WLBZiaaqP4DtU= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/bytestream v0.0.0-20240325203815-454cdb8f5daa h1:wBkzraZsSqhj1M4L/nMrljUU6XasJkgHvUsq8oRGwF0= google.golang.org/genproto/googleapis/bytestream v0.0.0-20240730163845-b1a4ccb954bf h1:T4tsZBlZYXK3j40sQNP5MBO32I+rn6ypV1PpklsiV8k= google.golang.org/genproto/googleapis/bytestream v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:5/MT647Cn/GGhwTpXC7QqcaR5Cnee4v4MKCU1/nwnIQ= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20240823204242-4ba0660f739c h1:5SFTbgH011A1/MostoGp5314PMnSH9ZLxZX/xynmp64= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20240823204242-4ba0660f739c/go.mod h1:gQizMG9jZ0L2ADJaM+JdZV4yTCON/CQpnHRPoM+54w4= google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= @@ -1256,15 +1563,23 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= +google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2-0.20240529085009-ca837e5c658b/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= +gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1272,6 +1587,7 @@ gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= gopkg.in/telebot.v3 v3.2.1 h1:3I4LohaAyJBiivGmkfB+CiVu7QFOWkuZ4+KHgO/G3rs= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= @@ -1279,6 +1595,8 @@ k8s.io/code-generator v0.31.0 h1:w607nrMi1KeDKB3/F/J4lIoOgAwc+gV9ZKew4XRfMp8= k8s.io/code-generator v0.31.0/go.mod h1:84y4w3es8rOJOUUP1rLsIiGlO1JuEaPFXQPA9e/K6U0= k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo= +k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7 h1:cErOOTkQ3JW19o4lo91fFurouhP8NcoBvb7CkvhZZpk= +k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= diff --git a/package.json b/package.json index 8f7a0c8da900c..873c151fdd4e6 100644 --- a/package.json +++ b/package.json @@ -247,7 +247,8 @@ }, "dependencies": { "@emotion/css": "11.11.2", - "@emotion/react": "11.11.4", + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", "@fingerprintjs/fingerprintjs": "^3.4.2", "@floating-ui/react": "0.26.22", "@formatjs/intl-durationformat": "^0.2.4", @@ -283,6 +284,7 @@ "@locker/near-membrane-shared-dom": "0.13.6", "@msagl/core": "^1.1.19", "@msagl/parser": "^1.1.19", + "@mui/material": "^6.0.0", "@opentelemetry/api": "1.9.0", "@opentelemetry/exporter-collector": "0.25.0", "@opentelemetry/semantic-conventions": "1.25.1", @@ -360,6 +362,8 @@ "rc-tree": "5.8.8", "re-resizable": "6.9.17", "react": "18.2.0", + "react-ace": "^12.0.0", + "react-datepicker": "^7.3.0", "react-diff-viewer": "^3.1.1", "react-dom": "18.2.0", "react-draggable": "4.4.6", diff --git a/packages/grafana-data/src/dataframe/ArrayDataFrame.ts b/packages/grafana-data/src/dataframe/ArrayDataFrame.ts index ae8b821175ef2..8d35ca28d8547 100644 --- a/packages/grafana-data/src/dataframe/ArrayDataFrame.ts +++ b/packages/grafana-data/src/dataframe/ArrayDataFrame.ts @@ -1,4 +1,4 @@ -import { QueryResultMeta } from '../types'; +import { QueryResultMeta } from '../types/data'; import { Field, FieldType, DataFrame, TIME_SERIES_VALUE_FIELD_NAME } from '../types/dataFrame'; import { guessFieldTypeForField } from './processDataFrame'; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx index fa389edb7792f..3589bf9420464 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx @@ -2,7 +2,7 @@ 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, ReactElement, ReactNode, useEffect } from 'react'; +import { memo, createRef, useState, ReactNode, useEffect } from 'react'; import { rangeUtil, diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx index 0da4357649f9b..bb7b75ceb1363 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx @@ -281,7 +281,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRang background: theme.colors.background.primary, boxShadow: theme.shadows.z3, width: `${isFullscreen ? '546px' : '262px'}`, - borderRadius: '6px', + borderRadius: theme.shape.radius.default, border: `1px solid ${theme.colors.border.weak}`, [`${isReversed ? 'left' : 'right'}`]: 0, }), @@ -314,6 +314,10 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRang spacing: css({ marginTop: '16px', }), + scrollContent: css({ + overflowY: 'auto', + scrollbarWidth: 'thin', + }), }; }); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx index 51a2613ca7d60..686b29122a2a7 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { getTimeZoneInfo, GrafanaTheme2, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { stylesFactory, useStyles2 } from '../../../themes'; +import { stylesFactory, useStyles2, useTheme2 } from '../../../themes'; import { t, Trans } from '../../../utils/i18n'; import { Button } from '../../Button'; import { Field } from '../../Forms/Field'; @@ -36,6 +36,7 @@ export const TimePickerFooter = (props: Props) => { } = props; const [isEditing, setEditing] = useState(false); const [editMode, setEditMode] = useState('tz'); + const theme = useTheme2(); const timeSettingsId = useId(); const timeZoneSettingsId = useId(); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx index a4e6b15b667d5..46d43108c1db2 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx @@ -195,17 +195,37 @@ export const TimeRangeContent = (props: Props) => { {fyTooltip}
- + +
+ +
- {/* @ts-ignore */} - {React.cloneElement(typeof children === 'function' ? children(visible) : children, { - ref: setTriggerRef, + {React.cloneElement(children, { + ref: refs.setReference, + ...getReferenceProps(), })} {show && ( @@ -105,8 +105,7 @@ export const Dropdown = React.memo(({ children, overlay, placement, offset, onVi timeout={{ appear: animationDuration, exit: 0, enter: 0 }} classNames={animationStyles} > - {/* @ts-ignore */} -
{ReactUtils.renderOrCallToRender(overlay, {})}
+
{ReactUtils.renderOrCallToRender(overlay, { ...getFloatingProps() })}
diff --git a/packages/grafana-ui/src/components/Icon/Icon.tsx b/packages/grafana-ui/src/components/Icon/Icon.tsx index 63db92698fe19..d760c3a318587 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.tsx +++ b/packages/grafana-ui/src/components/Icon/Icon.tsx @@ -42,20 +42,10 @@ const getIconStyles = (theme: GrafanaTheme2) => { }; }; -export const Icon = React.forwardRef( - ({ size = 'md', type = 'default', name, className, style, title = '', ...divElementProps }, ref): JSX.Element => { +export const Icon = React.forwardRef( + ({ size = 'md', type = 'default', name, className, style, title = '', ...rest }, ref) => { const styles = useStyles2(getIconStyles); - /* Temporary solution to display also font awesome icons */ - if (name?.startsWith('fa fa-')) { - /* @ts-ignore */ - return ; - } - - if (!cacheInitialized) { - initIconCache(); - } - if (!isIconName(name)) { console.warn('Icon component passed an invalid icon name', name); } @@ -80,17 +70,23 @@ export const Icon = React.forwardRef( ); return ( -
- {/* @ts-ignore */} - -
+ ); } ); diff --git a/packages/grafana-ui/src/components/Menu/MenuItem.tsx b/packages/grafana-ui/src/components/Menu/MenuItem.tsx index da942f51b4c17..11048b850c821 100644 --- a/packages/grafana-ui/src/components/Menu/MenuItem.tsx +++ b/packages/grafana-ui/src/components/Menu/MenuItem.tsx @@ -1,12 +1,14 @@ import { css, cx } from '@emotion/css'; -import React, { ReactElement, useCallback, useState, useRef, useImperativeHandle, CSSProperties } from 'react'; +import { ReactElement, useCallback, useState, useRef, useImperativeHandle, CSSProperties, AriaRole } from 'react'; +import * as React from 'react'; import { GrafanaTheme2, LinkTarget } from '@grafana/data'; import { useStyles2 } from '../../themes'; import { getFocusStyles } from '../../themes/mixins'; -import { IconName } from '../../types'; +import { IconName } from '../../types/icon'; import { Icon } from '../Icon/Icon'; +import { Stack } from '../Layout/Stack/Stack'; import { SubMenu } from './SubMenu'; @@ -14,9 +16,11 @@ import { SubMenu } from './SubMenu'; export type MenuItemElement = HTMLAnchorElement & HTMLButtonElement & HTMLDivElement; /** @internal */ -export interface MenuItemProps { +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 */ @@ -26,7 +30,7 @@ export interface MenuItemProps { /** Icon of the menu item */ icon?: IconName; /** Role of the menu item */ - role?: string; + role?: AriaRole; /** Url of the menu item */ url?: string; /** Handler for the click behaviour */ @@ -48,6 +52,8 @@ export interface MenuItemProps { shortcut?: string; /** Test id for e2e tests and fullstory*/ testId?: string; + /* Optional component that will be shown together with other options. Does not get passed any props. */ + component?: React.ComponentType; } /** @internal */ @@ -57,6 +63,7 @@ export const MenuItem = React.memo( url, icon, label, + description, ariaLabel, ariaChecked, target, @@ -66,7 +73,7 @@ export const MenuItem = React.memo( disabled, destructive, childItems, - role = 'menuitem', + role, tabIndex = -1, customSubMenuContainerStyles, shortcut, @@ -75,7 +82,6 @@ export const MenuItem = React.memo( const styles = useStyles2(getStyles); const [isActive, setIsActive] = useState(active); const [isSubMenuOpen, setIsSubMenuOpen] = useState(false); - const [openedWithArrow, setOpenedWithArrow] = useState(false); const onMouseEnter = useCallback(() => { if (disabled) { return; @@ -104,6 +110,7 @@ export const MenuItem = React.memo( }, className ); + const disabledProps = { [ItemElement === 'button' ? 'disabled' : 'aria-disabled']: disabled, ...(ItemElement === 'a' && disabled && { href: undefined, onClick: undefined }), @@ -123,7 +130,6 @@ export const MenuItem = React.memo( event.stopPropagation(); if (hasSubMenu) { setIsSubMenuOpen(true); - setOpenedWithArrow(true); setIsActive(true); } break; @@ -150,7 +156,10 @@ export const MenuItem = React.memo( onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onKeyDown={handleKeys} - role={url === undefined ? role : undefined} + // If there's no URL, then set either the role from the props, or fallback to menuitem + // If there IS a URL, then use the role from props - which will result in this either being a + // link (default role of an anchor), or whatever the user of this component specified + role={!url ? role || 'menuitem' : role} data-role="menuitem" // used to identify menuitem in Menu.tsx ref={localRef} data-testid={testId} @@ -159,34 +168,36 @@ export const MenuItem = React.memo( tabIndex={tabIndex} {...disabledProps} > - <> - {/* @ts-ignore */} + {icon && } - {label} - + {label}
{hasShortcut && (
- {/* @ts-ignore */} - + {shortcut}
)} {hasSubMenu && ( - <> - {/* @ts-ignore */} - - + )}
- +
+ {description && ( +
+ {description} +
+ )} + {props.component ? : null} ); }) @@ -202,7 +213,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, @@ -210,7 +222,7 @@ const getStyles = (theme: GrafanaTheme2) => { width: '100%', position: 'relative', - '&:hover, &:focus, &:focus-visible': { + '&:hover, &:focus-visible': { background: theme.colors.action.hover, color: theme.colors.text.primary, textDecoration: 'none', @@ -239,7 +251,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', @@ -248,8 +260,6 @@ const getStyles = (theme: GrafanaTheme2) => { }), icon: css({ opacity: 0.7, - marginRight: '10px', - marginLeft: '-4px', color: theme.colors.text.secondary, }), rightWrapper: css({ @@ -257,9 +267,6 @@ const getStyles = (theme: GrafanaTheme2) => { alignItems: 'center', marginLeft: 'auto', }), - shortcutIcon: css({ - marginRight: theme.spacing(1), - }), withShortcut: css({ minWidth: theme.spacing(10.5), }), @@ -271,5 +278,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 398d34c1cc1f2..696a71c9a757c 100644 --- a/packages/grafana-ui/src/components/Menu/SubMenu.tsx +++ b/packages/grafana-ui/src/components/Menu/SubMenu.tsx @@ -1,5 +1,5 @@ import { css, cx } from '@emotion/css'; -import React, { CSSProperties, ReactElement, useEffect, useRef, useState } from 'react'; +import { memo, CSSProperties, ReactElement, useEffect, useRef, useState } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; @@ -17,10 +17,6 @@ export interface SubMenuProps { items?: Array>; /** Open */ isOpen: boolean; - /** Marks whether subMenu was opened with arrow */ - openedWithArrow: boolean; - /** Changes value of openedWithArrow */ - setOpenedWithArrow: (openedWithArrow: boolean) => void; /** Closes the subMenu */ close: () => void; /** Custom style */ @@ -28,48 +24,42 @@ export interface SubMenuProps { } /** @internal */ -export const SubMenu = React.memo( - ({ items, isOpen, openedWithArrow, setOpenedWithArrow, close, customStyle }: SubMenuProps) => { - const styles = useStyles2(getStyles); - const localRef = useRef(null); - const [handleKeys] = useMenuFocus({ - localRef, - isMenuOpen: isOpen, - openedWithArrow, - setOpenedWithArrow, - close, - }); +export const SubMenu = memo(({ items, isOpen, close, customStyle }: SubMenuProps) => { + const styles = useStyles2(getStyles); + const localRef = useRef(null); + const [handleKeys] = useMenuFocus({ + localRef, + isMenuOpen: isOpen, + close, + }); - const [pushLeft, setPushLeft] = useState(false); - useEffect(() => { - if (isOpen && localRef.current) { - setPushLeft(isElementOverflowing(localRef.current)); - } - }, [isOpen]); + const [pushLeft, setPushLeft] = useState(false); + useEffect(() => { + if (isOpen && localRef.current) { + setPushLeft(isElementOverflowing(localRef.current)); + } + }, [isOpen]); - return ( - <> -
- {/* @ts-ignore */} - -
- {isOpen && ( -
-
- {/* @ts-ignore */} - {items} -
+ return ( + <> +
+ +
+ {isOpen && ( +
+
+ {items}
- )} - - ); - } -); +
+ )} + + ); +}); SubMenu.displayName = 'SubMenu'; @@ -90,7 +80,7 @@ const getStyles = (theme: GrafanaTheme2) => { background: theme.colors.background.primary, boxShadow: theme.shadows.z3, display: 'inline-block', - borderRadius: theme.shape.borderRadius(), + borderRadius: theme.shape.radius.default, }), pushLeft: css({ right: '100%', diff --git a/packages/grafana-ui/src/components/Table/Table.tsx b/packages/grafana-ui/src/components/Table/Table.tsx index cc8a786cb5217..dea703181eb07 100644 --- a/packages/grafana-ui/src/components/Table/Table.tsx +++ b/packages/grafana-ui/src/components/Table/Table.tsx @@ -338,7 +338,7 @@ export const Table = memo((props: Props) => {
) : (
- {noValuesDisplayText} + {NO_DATA_TEXT}
)} {footerItems && ( diff --git a/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx b/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx index 5e2ab7cfe2ce2..d26f3a4cc6616 100644 --- a/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx +++ b/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx @@ -1,5 +1,6 @@ +/* eslint-disable @grafana/no-unreduced-motion */ import { cx, css } from '@emotion/css'; -import React, { forwardRef, ButtonHTMLAttributes, ReactNode } from 'react'; +import { forwardRef, ButtonHTMLAttributes, ReactNode } from 'react'; import { GrafanaTheme2, IconName, isIconName } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; diff --git a/pkg/aggregator/go.mod b/pkg/aggregator/go.mod index 55398f00f5e60..60f1d9187cfbe 100644 --- a/pkg/aggregator/go.mod +++ b/pkg/aggregator/go.mod @@ -3,89 +3,92 @@ module github.com/grafana/grafana/pkg/aggregator go 1.23.0 require ( - github.com/emicklei/go-restful/v3 v3.11.0 - github.com/grafana/grafana-plugin-sdk-go v0.244.0 + github.com/emicklei/go-restful/v3 v3.12.1 + github.com/grafana/grafana-plugin-sdk-go v0.245.0 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435 github.com/grafana/grafana/pkg/semconv v0.0.0-20240808213237-f4d2e064f435 github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/otel v1.28.0 + go.opentelemetry.io/otel v1.29.0 k8s.io/api v0.31.0 k8s.io/apimachinery v0.31.0 k8s.io/apiserver v0.31.0 k8s.io/client-go v0.31.0 k8s.io/component-base v0.31.0 k8s.io/klog/v2 v2.130.1 - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 + k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 sigs.k8s.io/structured-merge-diff/v4 v4.4.1 ) require ( - github.com/BurntSushi/toml v1.3.2 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/apache/arrow/go/v15 v15.0.2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/bufbuild/protocompile v0.14.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect - github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 // indirect + github.com/chromedp/cdproto v0.0.0-20240810084448-b931b754e476 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 // indirect + github.com/elazarl/goproxy v0.0.0-20240726154733-8b0c20506380 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/getkin/kin-openapi v0.125.0 // indirect + github.com/getkin/kin-openapi v0.127.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/btree v1.1.2 // indirect - github.com/google/cel-go v0.20.1 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/cel-go v0.21.0 // indirect github.com/google/flatbuffers v24.3.25+incompatible // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grafana/otel-profiling-go v0.5.1 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-plugin v1.6.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/invopop/yaml v0.3.1 // indirect + github.com/jhump/protoreflect v1.16.0 // indirect github.com/jonboulle/clockwork v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/magefile/mage v1.15.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -97,9 +100,9 @@ require ( github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.20.0 // indirect + github.com/prometheus/client_golang v1.20.2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.57.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -114,25 +117,25 @@ require ( github.com/urfave/cli v1.22.15 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - go.etcd.io/etcd/api/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/v3 v3.5.14 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.opentelemetry.io/contrib/propagators/jaeger v1.28.0 // indirect - go.opentelemetry.io/contrib/samplers/jaegerremote v0.22.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.etcd.io/etcd/api/v3 v3.5.15 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect + go.etcd.io/etcd/client/v3 v3.5.15 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.29.0 // indirect + go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect - golang.org/x/mod v0.18.0 // indirect + golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect + golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect @@ -140,20 +143,20 @@ require ( golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect - gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/grpc v1.65.0 // indirect + gonum.org/v1/gonum v0.15.1 // indirect + google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/grpc v1.66.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + k8s.io/utils v0.0.0-20240821151609-f90d01438635 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/pkg/aggregator/go.sum b/pkg/aggregator/go.sum index 365a5e0f8df2f..7907a6718b8cb 100644 --- a/pkg/aggregator/go.sum +++ b/pkg/aggregator/go.sum @@ -1,11 +1,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/apache/arrow/go/v15 v15.0.2 h1:60IliRbiyTWCWjERBCkO1W4Qun9svcYoZrSLcyOsMLE= github.com/apache/arrow/go/v15 v15.0.2/go.mod h1:DGXsR3ajT524njufqf95822i+KTh+yea1jass9YXgjA= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -16,8 +17,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -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/bufbuild/protocompile v0.14.0 h1:z3DW4IvXE5G/uTOnSQn+qwQQxvhckkTWLS/0No/o7KU= +github.com/bufbuild/protocompile v0.14.0/go.mod h1:N6J1NYzkspJo3ZwyL4Xjvli86XOj1xq4qAasUFxGups= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -25,8 +26,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= -github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 h1:RdCf9hH3xq5vJifrjGB7zQlFkdRB3pAppcX2helDq2U= -github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/cdproto v0.0.0-20240810084448-b931b754e476 h1:VnjHsRXCRti7Av7E+j4DCha3kf68echfDzQ+wD11SBU= +github.com/chromedp/cdproto v0.0.0-20240810084448-b931b754e476/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= @@ -42,13 +43,12 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M= -github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/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 v0.0.0-20240726154733-8b0c20506380 h1:1NyRx2f4W4WBRyg0Kys0ZbaNmDDzZ2R/C7DTi+bbsJ0= +github.com/elazarl/goproxy v0.0.0-20240726154733-8b0c20506380/go.mod h1:thX175TtLTzLj3p7N/Q9IiKZ7NF+p72cvL91emV0hzo= 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.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 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= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -56,8 +56,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -65,8 +65,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/getkin/kin-openapi v0.125.0 h1:jyQCyf2qXS1qvs2U00xQzkGCqYPhEhZDmSmVt65fXno= -github.com/getkin/kin-openapi v0.125.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= +github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= +github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -79,8 +79,8 @@ github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -88,8 +88,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= 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/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -104,10 +104,10 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= -github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= +github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= @@ -119,8 +119,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -128,10 +128,10 @@ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/grafana-plugin-sdk-go v0.244.0 h1:ZZxHbiiF6QcsnlbPFyZGmzNDoTC1pLeHXUQYoskWt5c= -github.com/grafana/grafana-plugin-sdk-go v0.244.0/go.mod h1:H3FXrJMUlwocQ6UYj8Ds5I9EzRAVOcdRcgaRE3mXQqk= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/grafana-plugin-sdk-go v0.245.0 h1:2KCKA86//O20ffL6WKzHGx5scBbdV7GyEFGnH8Hdv7M= +github.com/grafana/grafana-plugin-sdk-go v0.245.0/go.mod h1:1X8Kgo/SK91Qo1WBCKjPSKrfgjpQys1OkQsHhA78TLg= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435 h1:lmw60EW7JWlAEvgggktOyVkH4hF1m/+LSF/Ap0NCyi8= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435/go.mod h1:ORVFiW/KNRY52lNjkGwnFWCxNVfE97bJG2jr2fetq0I= github.com/grafana/grafana/pkg/semconv v0.0.0-20240808213237-f4d2e064f435 h1:SNEeqY22DrGr5E9kGF1mKSqlOom14W9+b1u4XEGJowA= @@ -150,8 +150,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= @@ -164,8 +164,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= -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/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg= +github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -181,8 +181,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -211,8 +211,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= @@ -247,23 +247,22 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= -github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= +github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= +github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -329,46 +328,46 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= +go.etcd.io/etcd/api/v3 v3.5.15 h1:3KpLJir1ZEBrYuV2v+Twaa/e2MdDCEZ/70H+lzEiwsk= +go.etcd.io/etcd/api/v3 v3.5.15/go.mod h1:N9EhGzXq58WuMllgH9ZvnEr7SI9pS0k0+DHZezGp7jM= +go.etcd.io/etcd/client/pkg/v3 v3.5.15 h1:fo0HpWz/KlHGMCC+YejpiCmyWDEuIpnTDzpJLB5fWlA= +go.etcd.io/etcd/client/pkg/v3 v3.5.15/go.mod h1:mXDI4NAOwEiszrHCb0aqfAYNCrZP4e9hRca3d1YK8EU= go.etcd.io/etcd/client/v2 v2.305.13 h1:RWfV1SX5jTU0lbCvpVQe3iPQeAHETWdOTb6pxhd77C8= go.etcd.io/etcd/client/v2 v2.305.13/go.mod h1:iQnL7fepbiomdXMb3om1rHq96htNNGv2sJkEcZGDRRg= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= +go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4= +go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU= go.etcd.io/etcd/pkg/v3 v3.5.13 h1:st9bDWNsKkBNpP4PR1MvM/9NqUPfvYZx/YXegsYEH8M= go.etcd.io/etcd/pkg/v3 v3.5.13/go.mod h1:N+4PLrp7agI/Viy+dUYpX7iRtSPvKq+w8Y14d1vX+m0= go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA= go.etcd.io/etcd/raft/v3 v3.5.13/go.mod h1:uUFibGLn2Ksm2URMxN1fICGhk8Wu96EfDQyuLhAcAmw= go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok= go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 h1:IVtyPth4Rs5P8wIf0mP2KVKFNTJ4paX9qQ4Hkh5gFdc= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0/go.mod h1:ImRBLMJv177/pwiLZ7tU7HDGNdBv7rS0HQ99eN/zBl8= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/contrib/propagators/jaeger v1.28.0 h1:xQ3ktSVS128JWIaN1DiPGIjcH+GsvkibIAVRWFjS9eM= -go.opentelemetry.io/contrib/propagators/jaeger v1.28.0/go.mod h1:O9HIyI2kVBrFoEwQZ0IN6PHXykGoit4mZV2aEjkTRH4= -go.opentelemetry.io/contrib/samplers/jaegerremote v0.22.0 h1:OYxqumWcd1yaV/qvCt1B7Sru9OeUNGjeXq/oldx3AGk= -go.opentelemetry.io/contrib/samplers/jaegerremote v0.22.0/go.mod h1:2tZTRqCbvx7nG57wUwd5NQpNVujOWnR84iPLllIH0Ok= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0 h1:U9ge/19g8pkNXL+0eqeWgiJAd8nSmmvbvwehqyxU/Lc= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0/go.mod h1:dmNhUi0Tl5v/3e0QNp7/3KLMvAPoHh4lMbZU319UkM0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/contrib/propagators/jaeger v1.29.0 h1:+YPiqF5rR6PqHBlmEFLPumbSP0gY0WmCGFayXRcCLvs= +go.opentelemetry.io/contrib/propagators/jaeger v1.29.0/go.mod h1:6PD7q7qquWSp3Z4HeM3e/2ipRubaY1rXZO8NIHVDZjs= +go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 h1:qKi9ntCcronqWqfuKxqrxZlZd82jXJEgGiAWH1+phxo= +go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0/go.mod h1:1kbAgQa5lgYC3rC6cE3jSxQ/Q13l33wv/WI8U+htwag= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -387,16 +386,16 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -455,35 +454,35 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= +gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c h1:TYOEhrQMrNDTAd2rX9m+WgGr8Ku6YNuj1D7OX6rWSok= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c/go.mod h1:2rC5OendXvZ8wGEo/cSLheztrZDZaSoHanUcd1xtZnw= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= +google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -521,10 +520,10 @@ k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= +k8s.io/utils v0.0.0-20240821151609-f90d01438635 h1:2wThSvJoW/Ncn9TmQEYXRnevZXi2duqHWf5OX9S3zjI= +k8s.io/utils v0.0.0-20240821151609-f90d01438635/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 0ed47cfa59c02..df13025462d23 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -847,38 +847,31 @@ func (hs *HTTPServer) GetDashboardVersions(c *contextmodel.ReqContext) response. // 500: internalServerError func (hs *HTTPServer) GetDashboardVersion(c *contextmodel.ReqContext) response.Response { var dashID int64 - var err error - var dash *models.Dashboard + var err error dashUID := web.Params(c.Req)[":uid"] + + var dash *dashboards.Dashboard if dashUID == "" { dashID, err = strconv.ParseInt(web.Params(c.Req)[":dashboardId"], 10, 64) if err != nil { return response.Error(http.StatusBadRequest, "dashboardId is invalid", err) } - } else { - q := models.GetDashboardQuery{ - OrgId: c.SignedInUser.OrgID, - Uid: dashUID, - } - if err := hs.DashboardService.GetDashboard(c.Req.Context(), &q); err != nil { - return response.Error(http.StatusBadRequest, "failed to get dashboard by UID", err) - } - dashID = q.Result.Id - dash = q.Result } - guardian := guardian.New(c.Req.Context(), dashID, c.OrgID, c.SignedInUser) - canSave := true - if canSave, err = guardian.CanSave(); err != nil || !canSave { - return dashboardGuardianResponse(err) + dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), dashID, dashUID) + if rsp != nil { + return rsp } - if canView, err := guardian.CanView(); err != nil || !canView { + + guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.SignedInUser.GetOrgID(), c.SignedInUser) + if err != nil { + return response.Err(err) + } + + if canSave, err := guardian.CanSave(); err != nil || !canSave { return dashboardGuardianResponse(err) } - canEdit, _ := guardian.CanEdit() - canAdmin, _ := guardian.CanAdmin() - canDelete, _ := guardian.CanDelete() version, _ := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 32) query := dashver.GetDashboardVersionQuery{ @@ -898,69 +891,20 @@ func (hs *HTTPServer) GetDashboardVersion(c *contextmodel.ReqContext) response.R creator = hs.getUserLogin(c.Req.Context(), res.CreatedBy) } - annotationPermissions := &dtos.AnnotationPermission{} - if !hs.AccessControl.IsDisabled() { - hs.getAnnotationPermissionsByScope(c, &annotationPermissions.Dashboard, accesscontrol.ScopeAnnotationsTypeDashboard) - hs.getAnnotationPermissionsByScope(c, &annotationPermissions.Organization, accesscontrol.ScopeAnnotationsTypeOrganization) - } - - hasPublicDashboard := false - publicDashboardEnabled := false - // If public dashboards is enabled and we have a public dashboard, update meta values - if hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) { - publicDashboard, err := hs.PublicDashboardsApi.PublicDashboardService.FindByDashboardUid(c.Req.Context(), c.OrgID, dash.Uid) - if err != nil && !errors.Is(err, publicdashboardModels.ErrPublicDashboardNotFound) { - return response.Error(500, "Error while retrieving public dashboards", err) - } - if publicDashboard != nil { - hasPublicDashboard = true - publicDashboardEnabled = publicDashboard.IsEnabled - } + dashVersionMeta := &dashver.DashboardVersionMeta{ + ID: res.ID, + DashboardID: res.DashboardID, + DashboardUID: dash.UID, + Data: res.Data, + ParentVersion: res.ParentVersion, + RestoredFrom: res.RestoredFrom, + Version: res.Version, + Created: res.Created, + Message: res.Message, + CreatedBy: creator, } - meta := dtos.DashboardMeta{ - Slug: dash.Slug, - Type: models.DashTypeDB, - CanStar: c.IsSignedIn, - CanSave: canSave, - CanEdit: canEdit, - CanAdmin: canAdmin, - CanDelete: canDelete, - Created: dash.Created, - Updated: dash.Updated, - UpdatedBy: "Someone", - CreatedBy: creator, - Version: dash.Version, - HasACL: dash.HasACL, - IsFolder: dash.IsFolder, - FolderId: dash.FolderId, - Url: dash.GetUrl(), - FolderTitle: "General", - AnnotationsPermissions: annotationPermissions, - PublicDashboardEnabled: publicDashboardEnabled, - HasPublicDashboard: hasPublicDashboard, - } - - // lookup folder title - if dash.FolderId > 0 { - query := models.GetDashboardQuery{Id: dash.FolderId, OrgId: c.OrgID} - if err := hs.DashboardService.GetDashboard(c.Req.Context(), &query); err != nil { - if errors.Is(err, dashboards.ErrFolderNotFound) { - return response.Error(404, "Folder not found", err) - } - return response.Error(500, "Dashboard folder could not be read", err) - } - meta.FolderUid = query.Result.Uid - meta.FolderTitle = query.Result.Title - meta.FolderUrl = query.Result.GetUrl() - } - - dto := dtos.DashboardFullWithMeta{ - Dashboard: res.Data, - Meta: meta, - } - - return response.JSON(http.StatusOK, dto) + return response.JSON(http.StatusOK, dashVersionMeta) } // swagger:route POST /dashboards/calculate-diff dashboards calculateDashboardDiff diff --git a/pkg/api/dtos/dashboard.go b/pkg/api/dtos/dashboard.go index 9d8f96f8c7aa6..66a8922a4f1a3 100644 --- a/pkg/api/dtos/dashboard.go +++ b/pkg/api/dtos/dashboard.go @@ -35,6 +35,7 @@ type DashboardMeta struct { ProvisionedExternalId string `json:"provisionedExternalId"` AnnotationsPermissions *dashboardsV0.AnnotationPermission `json:"annotationsPermissions"` PublicDashboardEnabled bool `json:"publicDashboardEnabled,omitempty"` + HasPublicDashboard bool `json:"hasPublicDashboard,omitempty"` } type DashboardFullWithMeta struct { diff --git a/pkg/api/plugin_resource_test.go b/pkg/api/plugin_resource_test.go index ff887d83f7264..9ac339edbde17 100644 --- a/pkg/api/plugin_resource_test.go +++ b/pkg/api/plugin_resource_test.go @@ -50,20 +50,8 @@ func TestCallResource(t *testing.T) { cfg.StaticRootPath = staticRootPath cfg.Azure = &azsettings.AzureSettings{} - coreRegistry := coreplugin.ProvideCoreRegistry(nil, &cloudwatch.CloudWatchService{}, nil, nil, nil, nil, + coreRegistry := coreplugin.ProvideCoreRegistry(tracing.InitializeTracerForTest(), nil, &cloudwatch.CloudWatchService{}, nil, nil, nil, nil, nil, nil, nil, nil, testdatasource.ProvideService(), nil, nil, nil, nil, nil, nil, nil) - pCfg, err := config.ProvideConfig(setting.ProvideProvider(cfg), cfg, featuremgmt.WithFeatures()) - require.NoError(t, err) - reg := registry.ProvideService() - angularInspector, err := angularinspector.NewStaticInspector() - require.NoError(t, err) - l := loader.ProvideService(pCfg, fakes.NewFakeLicensingService(), signature.NewUnsignedAuthorizer(pCfg), - reg, provider.ProvideService(coreRegistry), finder.NewLocalFinder(pCfg.DevMode), fakes.NewFakeRoleRegistry(), - assetpath.ProvideService(pluginscdn.ProvideService(pCfg)), signature.ProvideService(statickey.New()), - angularInspector, &fakes.FakeOauthService{}) - srcs := sources.ProvideService(cfg, pCfg) - ps, err := store.ProvideService(reg, srcs, l) - require.NoError(t, err) testCtx := pluginsintegration.CreateIntegrationTestCtx(t, cfg, coreRegistry) diff --git a/pkg/apimachinery/go.mod b/pkg/apimachinery/go.mod index 418e3beab91d6..7cae5389a2ccb 100644 --- a/pkg/apimachinery/go.mod +++ b/pkg/apimachinery/go.mod @@ -3,22 +3,22 @@ module github.com/grafana/grafana/pkg/apimachinery go 1.23.0 require ( - github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db // @grafana/identity-access-team - github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db // @grafana/identity-access-team + github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 // @grafana/identity-access-team + github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2 // @grafana/identity-access-team github.com/stretchr/testify v1.9.0 k8s.io/apimachinery v0.31.0 k8s.io/apiserver v0.31.0 - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 + k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 ) require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -37,14 +37,14 @@ require ( golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/grpc v1.65.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/grpc v1.66.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + k8s.io/utils v0.0.0-20240821151609-f90d01438635 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/pkg/apimachinery/go.sum b/pkg/apimachinery/go.sum index 66b4df6cb6c4a..46c32b3e12732 100644 --- a/pkg/apimachinery/go.sum +++ b/pkg/apimachinery/go.sum @@ -2,8 +2,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= @@ -12,8 +12,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -28,10 +28,10 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db h1:z++X4DdoX+aNlZNT1ZY4cykiFay4+f077pa0AG48SGg= -github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db/go.mod h1:ptt910z9KFfpVSIbSbXvTRR7tS19mxD7EtmVbbJi/WE= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= +github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 h1:SU+p1ck8037cz6F8W38PIL9MzRb6YMeNqc7+GHDuqiU= +github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2/go.mod h1:PFzXbCrn0GIpN4KwT6NP1l5Z1CPLfmKHnYx8rZzQcyY= +github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2 h1:YTF1Y1BYCDkD7ssmbhzRqXlxevsYpXPmOnoO8qbOue8= +github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -131,10 +131,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= +google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -154,10 +154,10 @@ k8s.io/apiserver v0.31.0 h1:p+2dgJjy+bk+B1Csz+mc2wl5gHwvNkC9QJV+w55LVrY= k8s.io/apiserver v0.31.0/go.mod h1:KI9ox5Yu902iBnnyMmy7ajonhKnkeZYJhTZ/YI+WEMk= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= +k8s.io/utils v0.0.0-20240821151609-f90d01438635 h1:2wThSvJoW/Ncn9TmQEYXRnevZXi2duqHWf5OX9S3zjI= +k8s.io/utils v0.0.0-20240821151609-f90d01438635/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/pkg/apimachinery/identity/wrapper.go b/pkg/apimachinery/identity/wrapper.go index 299a977a3cac0..a8171dc17ac06 100644 --- a/pkg/apimachinery/identity/wrapper.go +++ b/pkg/apimachinery/identity/wrapper.go @@ -102,3 +102,8 @@ func (i *IDClaimsWrapper) Scopes() []string { func (i *IDClaimsWrapper) Subject() string { return "" } + +// IsNil implements claims.AccessClaims. +func (i *IDClaimsWrapper) IsNil() bool { + return i.Source == nil +} diff --git a/pkg/apiserver/go.mod b/pkg/apiserver/go.mod index 5e7937c7e4c00..10d0f6a42cd6c 100644 --- a/pkg/apiserver/go.mod +++ b/pkg/apiserver/go.mod @@ -4,16 +4,16 @@ go 1.23.0 require ( github.com/google/go-cmp v0.6.0 - github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db + github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1 - github.com/prometheus/client_golang v1.20.0 + github.com/prometheus/client_golang v1.20.2 github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/otel/trace v1.28.0 + go.opentelemetry.io/otel/trace v1.29.0 k8s.io/apimachinery v0.31.0 k8s.io/apiserver v0.31.0 k8s.io/component-base v0.31.0 k8s.io/klog/v2 v2.130.1 - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 + k8s.io/utils v0.0.0-20240821151609-f90d01438635 ) require ( @@ -23,18 +23,19 @@ require ( github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/btree v1.1.2 // indirect + github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/jonboulle/clockwork v0.4.0 // indirect @@ -48,16 +49,19 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.57.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/x448/float16 v0.8.4 // indirect - go.etcd.io/etcd/api/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/v3 v3.5.14 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.etcd.io/etcd/api/v3 v3.5.15 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect + go.etcd.io/etcd/client/v3 v3.5.15 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/net v0.28.0 // indirect @@ -66,18 +70,17 @@ require ( golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.22.0 // indirect - google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/grpc v1.65.0 // indirect + google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/grpc v1.66.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.31.0 // indirect k8s.io/client-go v0.31.0 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/pkg/apiserver/go.sum b/pkg/apiserver/go.sum index 66724337e95cd..39766e6c64f9c 100644 --- a/pkg/apiserver/go.sum +++ b/pkg/apiserver/go.sum @@ -23,8 +23,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 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= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -41,8 +41,8 @@ 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-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -60,8 +60,8 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= 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= @@ -71,14 +71,14 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2 h1:YTF1Y1BYCDkD7ssmbhzRqXlxevsYpXPmOnoO8qbOue8= +github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1 h1:ItDcDxUjVLPKja+hogpqgW/kj8LxUL2qscelXIsN1Bs= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1/go.mod h1:DkxMin+qOh1Fgkxfbt+CUfBqqsCQJMG9op8Os/irBPA= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= @@ -87,8 +87,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -131,16 +131,16 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= -github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= +github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= +github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= @@ -173,36 +173,36 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= +go.etcd.io/etcd/api/v3 v3.5.15 h1:3KpLJir1ZEBrYuV2v+Twaa/e2MdDCEZ/70H+lzEiwsk= +go.etcd.io/etcd/api/v3 v3.5.15/go.mod h1:N9EhGzXq58WuMllgH9ZvnEr7SI9pS0k0+DHZezGp7jM= +go.etcd.io/etcd/client/pkg/v3 v3.5.15 h1:fo0HpWz/KlHGMCC+YejpiCmyWDEuIpnTDzpJLB5fWlA= +go.etcd.io/etcd/client/pkg/v3 v3.5.15/go.mod h1:mXDI4NAOwEiszrHCb0aqfAYNCrZP4e9hRca3d1YK8EU= go.etcd.io/etcd/client/v2 v2.305.13 h1:RWfV1SX5jTU0lbCvpVQe3iPQeAHETWdOTb6pxhd77C8= go.etcd.io/etcd/client/v2 v2.305.13/go.mod h1:iQnL7fepbiomdXMb3om1rHq96htNNGv2sJkEcZGDRRg= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= +go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4= +go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU= go.etcd.io/etcd/pkg/v3 v3.5.13 h1:st9bDWNsKkBNpP4PR1MvM/9NqUPfvYZx/YXegsYEH8M= go.etcd.io/etcd/pkg/v3 v3.5.13/go.mod h1:N+4PLrp7agI/Viy+dUYpX7iRtSPvKq+w8Y14d1vX+m0= go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA= go.etcd.io/etcd/raft/v3 v3.5.13/go.mod h1:uUFibGLn2Ksm2URMxN1fICGhk8Wu96EfDQyuLhAcAmw= go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok= go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -272,8 +272,8 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -283,20 +283,20 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c h1:TYOEhrQMrNDTAd2rX9m+WgGr8Ku6YNuj1D7OX6rWSok= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c/go.mod h1:2rC5OendXvZ8wGEo/cSLheztrZDZaSoHanUcd1xtZnw= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= +google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -332,10 +332,10 @@ k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= +k8s.io/utils v0.0.0-20240821151609-f90d01438635 h1:2wThSvJoW/Ncn9TmQEYXRnevZXi2duqHWf5OX9S3zjI= +k8s.io/utils v0.0.0-20240821151609-f90d01438635/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/pkg/build/go.mod b/pkg/build/go.mod index c547676f24c2d..852fc46d1ed4e 100644 --- a/pkg/build/go.mod +++ b/pkg/build/go.mod @@ -17,7 +17,7 @@ replace github.com/prometheus/prometheus => github.com/prometheus/prometheus v0. require ( cloud.google.com/go/storage v1.43.0 // @grafana/grafana-backend-group - github.com/Masterminds/semver/v3 v3.2.0 // @grafana/grafana-release-guild + github.com/Masterminds/semver/v3 v3.3.0 // @grafana/grafana-release-guild github.com/aws/aws-sdk-go v1.55.5 // @grafana/aws-datasources github.com/blang/semver/v4 v4.0.0 // @grafana/grafana-release-guild github.com/docker/docker v26.0.2+incompatible // @grafana/grafana-release-guild @@ -32,27 +32,27 @@ require ( github.com/stretchr/testify v1.9.0 // @grafana/grafana-backend-group github.com/urfave/cli v1.22.15 // @grafana/grafana-backend-group github.com/urfave/cli/v2 v2.27.1 // @grafana/grafana-backend-group - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect; @grafana/plugins-platform-backend - go.opentelemetry.io/otel v1.28.0 // indirect; @grafana/grafana-backend-group - go.opentelemetry.io/otel/sdk v1.28.0 // indirect; @grafana/grafana-backend-group - go.opentelemetry.io/otel/trace v1.28.0 // indirect; @grafana/grafana-backend-group + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect; @grafana/plugins-platform-backend + go.opentelemetry.io/otel v1.29.0 // indirect; @grafana/grafana-backend-group + go.opentelemetry.io/otel/sdk v1.29.0 // indirect; @grafana/grafana-backend-group + go.opentelemetry.io/otel/trace v1.29.0 // indirect; @grafana/grafana-backend-group golang.org/x/crypto v0.26.0 // indirect; @grafana/grafana-backend-group - golang.org/x/mod v0.18.0 // @grafana/grafana-backend-group + golang.org/x/mod v0.20.0 // @grafana/grafana-backend-group golang.org/x/net v0.28.0 // indirect; @grafana/oss-big-tent @grafana/partner-datasources golang.org/x/oauth2 v0.22.0 // @grafana/identity-access-team golang.org/x/sync v0.8.0 // indirect; @grafana/alerting-backend golang.org/x/text v0.17.0 // indirect; @grafana/grafana-backend-group golang.org/x/time v0.6.0 // indirect; @grafana/grafana-backend-group - golang.org/x/tools v0.22.0 // indirect; @grafana/grafana-as-code - google.golang.org/api v0.191.0 // @grafana/grafana-backend-group - google.golang.org/grpc v1.65.0 // indirect; @grafana/plugins-platform-backend + golang.org/x/tools v0.24.0 // indirect; @grafana/grafana-as-code + google.golang.org/api v0.195.0 // @grafana/grafana-backend-group + google.golang.org/grpc v1.66.0 // indirect; @grafana/plugins-platform-backend google.golang.org/protobuf v1.34.2 // indirect; @grafana/plugins-platform-backend gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-backend ) require ( - cloud.google.com/go v0.115.0 // indirect - cloud.google.com/go/auth v0.8.1 // indirect + cloud.google.com/go v0.115.1 // indirect + cloud.google.com/go/auth v0.9.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect cloud.google.com/go/compute/metadata v0.5.0 // indirect cloud.google.com/go/iam v1.1.13 // indirect @@ -83,39 +83,38 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect golang.org/x/sys v0.24.0 // indirect - google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 // indirect; @grafana/grafana-backend-group - google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect + google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c // indirect; @grafana/grafana-backend-group + google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) require dagger.io/dagger v0.11.8-rc.2 require ( - cloud.google.com/go/longrunning v0.5.12 // indirect github.com/99designs/gqlgen v0.17.44 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Khan/genqlient v0.7.0 // indirect github.com/adrg/xdg v0.4.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/sosodev/duration v1.2.0 // indirect github.com/vektah/gqlparser/v2 v2.5.11 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect go.opentelemetry.io/otel/log v0.2.0-alpha // indirect go.opentelemetry.io/otel/sdk/log v0.2.0-alpha // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/pkg/build/go.sum b/pkg/build/go.sum index 5eef149b39b6c..b30a2f78a38ae 100644 --- a/pkg/build/go.sum +++ b/pkg/build/go.sum @@ -1,8 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= -cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.8.1 h1:QZW9FjC5lZzN864p13YxvAtGUlQ+KgRL+8Sg45Z6vxo= -cloud.google.com/go/auth v0.8.1/go.mod h1:qGVp/Y3kDRSDZ5gFD/XPUfYQ9xW1iI7q8RIRoCyBbJc= +cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ= +cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc= +cloud.google.com/go/auth v0.9.1 h1:+pMtLEV2k0AXKvs/tGZojuj6QaioxfUjOpMsG5Gtx+w= +cloud.google.com/go/auth v0.9.1/go.mod h1:Sw8ocT5mhhXxFklyhT12Eiy0ed6tTrPMCJjSI8KhYLk= cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= @@ -26,8 +26,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= -github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -145,8 +145,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksP github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -223,32 +223,32 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha h1:z2s6Zba+OUyayRv5m1AXWNUTGh57K1iMhy6emU5QT5Y= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha/go.mod h1:paOXXyUgPW6jYxYkP0pB47H2zHE1fPvMJ4E4G9LHOi0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= go.opentelemetry.io/otel/log v0.2.0-alpha h1:ixOPvMzserpqA07SENHvRzkZOsnG0XbPr74hv1AQ+n0= go.opentelemetry.io/otel/log v0.2.0-alpha/go.mod h1:vbFZc65yq4c4ssvXY43y/nIqkNJLxORrqw0L85P59LA= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= go.opentelemetry.io/otel/sdk/log v0.2.0-alpha h1:jGTkL/jroJ31jnP6jDl34N/mDOfRGGYZHcHsCM+5kWA= go.opentelemetry.io/otel/sdk/log v0.2.0-alpha/go.mod h1:Hd8Lw9FPGUM3pfY7iGMRvFaC2Nyau4Ajb5WnQ9OdIho= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= @@ -262,15 +262,15 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -320,33 +320,33 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.191.0 h1:cJcF09Z+4HAB2t5qTQM1ZtfL/PemsLFkcFG67qq2afk= -google.golang.org/api v0.191.0/go.mod h1:tD5dsFGxFza0hnQveGfVk9QQYKcfp+VzgRqyXFxE0+E= +google.golang.org/api v0.195.0 h1:Ude4N8FvTKnnQJHU48RFI40jOBgIrL8Zqr3/QeST6yU= +google.golang.org/api v0.195.0/go.mod h1:DOGRWuv3P8TU8Lnz7uQc4hyNqrBpMtD9ppW3wBJurgc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c h1:TYOEhrQMrNDTAd2rX9m+WgGr8Ku6YNuj1D7OX6rWSok= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c/go.mod h1:2rC5OendXvZ8wGEo/cSLheztrZDZaSoHanUcd1xtZnw= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= +google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/pkg/build/wire/go.mod b/pkg/build/wire/go.mod index 9d3457f15bd33..0c5c674272f22 100644 --- a/pkg/build/wire/go.mod +++ b/pkg/build/wire/go.mod @@ -6,10 +6,10 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/subcommands v1.2.0 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 - golang.org/x/tools v0.22.0 + golang.org/x/tools v0.24.0 ) require ( - golang.org/x/mod v0.18.0 // indirect + golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect ) diff --git a/pkg/build/wire/go.sum b/pkg/build/wire/go.sum index 11eeab6f14af4..d5bd1d0d841ce 100644 --- a/pkg/build/wire/go.sum +++ b/pkg/build/wire/go.sum @@ -4,9 +4,9 @@ github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= diff --git a/pkg/plugins/backendplugin/coreplugin/registry.go b/pkg/plugins/backendplugin/coreplugin/registry.go index a5e469dcc6577..e9faacbb5dc47 100644 --- a/pkg/plugins/backendplugin/coreplugin/registry.go +++ b/pkg/plugins/backendplugin/coreplugin/registry.go @@ -96,6 +96,9 @@ func ProvideCoreRegistry(tracer tracing.Tracer, am *azuremonitor.Service, cw *cl es *elasticsearch.Service, grap *graphite.Service, idb *influxdb.Service, lk *loki.Service, otsdb *opentsdb.Service, pr *prometheus.Service, t *tempo.Service, td *testdatasource.Service, pg *postgres.Service, my *mysql.Service, ms *mssql.Service, graf *grafanads.Service, pyroscope *pyroscope.Service, parca *parca.Service, dr *druid.Service) *Registry { + + sdktracing.InitDefaultTracer(tracer) + return NewRegistry(map[string]backendplugin.PluginFactoryFunc{ CloudWatch: asBackendPlugin(cw.Executor), CloudMonitoring: asBackendPlugin(cm), diff --git a/pkg/plugins/pfs/corelist/corelist_load_gen.go b/pkg/plugins/pfs/corelist/corelist_load_gen.go index a01a3cd72f904..36864aabe046d 100644 --- a/pkg/plugins/pfs/corelist/corelist_load_gen.go +++ b/pkg/plugins/pfs/corelist/corelist_load_gen.go @@ -23,7 +23,7 @@ func parsePluginOrPanic(path string, pkgname string, rt *thema.Runtime) pfs.Pars if err != nil { panic("could not create fs sub to " + path) } - pp, err := pfs.ParsePluginFS(sub, rt) + pp, err := pfs.ParsePluginFS(sub, rt, "public/app/plugins/"+pkgname) if err != nil { panic(fmt.Sprintf("error parsing plugin metadata for %s: %s", pkgname, err)) } diff --git a/pkg/promlib/go.mod b/pkg/promlib/go.mod index f3aea762a82a2..d78a49aaa90e0 100644 --- a/pkg/promlib/go.mod +++ b/pkg/promlib/go.mod @@ -3,50 +3,51 @@ module github.com/grafana/grafana/pkg/promlib go 1.23.0 require ( - github.com/grafana/dskit v0.0.0-20240805174438-dfa83b4ed2d3 - github.com/grafana/grafana-plugin-sdk-go v0.244.0 + github.com/grafana/dskit v0.0.0-20240827093408-28506cdffe6a + github.com/grafana/grafana-plugin-sdk-go v0.245.0 github.com/json-iterator/go v1.1.12 github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/prometheus/client_golang v1.20.0 - github.com/prometheus/common v0.55.0 + github.com/prometheus/client_golang v1.20.2 + github.com/prometheus/common v0.57.0 github.com/prometheus/prometheus v1.8.2-0.20221021121301-51a44e6657c3 github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/otel v1.28.0 - go.opentelemetry.io/otel/trace v1.28.0 - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f + go.opentelemetry.io/otel v1.29.0 + go.opentelemetry.io/otel/trace v1.29.0 + golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 k8s.io/apimachinery v0.31.0 ) require ( - github.com/BurntSushi/toml v1.3.2 // indirect - github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect + github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/apache/arrow/go/v15 v15.0.2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bufbuild/protocompile v0.14.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect - github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 // indirect + github.com/chromedp/cdproto v0.0.0-20240810084448-b931b754e476 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dennwc/varint v1.0.0 // indirect - github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/elazarl/goproxy v0.0.0-20240726154733-8b0c20506380 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/getkin/kin-openapi v0.125.0 // indirect + github.com/getkin/kin-openapi v0.127.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/flatbuffers v24.3.25+incompatible // indirect @@ -57,26 +58,27 @@ require ( github.com/gorilla/mux v1.8.1 // indirect github.com/grafana/otel-profiling-go v0.5.1 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect - github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db // indirect + github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-plugin v1.6.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/invopop/jsonschema v0.12.0 // indirect github.com/invopop/yaml v0.3.1 // indirect + github.com/jhump/protoreflect v1.16.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/magefile/mage v1.15.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -101,36 +103,36 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 // indirect - go.opentelemetry.io/contrib/propagators/jaeger v1.28.0 // indirect - go.opentelemetry.io/contrib/samplers/jaegerremote v0.22.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.29.0 // indirect + go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/goleak v1.3.0 // indirect - golang.org/x/mod v0.18.0 // indirect + golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect - gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/grpc v1.65.0 // indirect + gonum.org/v1/gonum v0.15.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/grpc v1.66.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 // indirect + k8s.io/utils v0.0.0-20240821151609-f90d01438635 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/pkg/promlib/go.sum b/pkg/promlib/go.sum index 8a3cfef31d138..dd2864aaec3b4 100644 --- a/pkg/promlib/go.sum +++ b/pkg/promlib/go.sum @@ -1,8 +1,9 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/apache/arrow/go/v15 v15.0.2 h1:60IliRbiyTWCWjERBCkO1W4Qun9svcYoZrSLcyOsMLE= github.com/apache/arrow/go/v15 v15.0.2/go.mod h1:DGXsR3ajT524njufqf95822i+KTh+yea1jass9YXgjA= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -13,8 +14,8 @@ github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPn github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -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/bufbuild/protocompile v0.14.0 h1:z3DW4IvXE5G/uTOnSQn+qwQQxvhckkTWLS/0No/o7KU= +github.com/bufbuild/protocompile v0.14.0/go.mod h1:N6J1NYzkspJo3ZwyL4Xjvli86XOj1xq4qAasUFxGups= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -23,8 +24,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= -github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 h1:RdCf9hH3xq5vJifrjGB7zQlFkdRB3pAppcX2helDq2U= -github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/cdproto v0.0.0-20240810084448-b931b754e476 h1:VnjHsRXCRti7Av7E+j4DCha3kf68echfDzQ+wD11SBU= +github.com/chromedp/cdproto v0.0.0-20240810084448-b931b754e476/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -34,16 +35,15 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= -github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M= -github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/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 v0.0.0-20240726154733-8b0c20506380 h1:1NyRx2f4W4WBRyg0Kys0ZbaNmDDzZ2R/C7DTi+bbsJ0= +github.com/elazarl/goproxy v0.0.0-20240726154733-8b0c20506380/go.mod h1:thX175TtLTzLj3p7N/Q9IiKZ7NF+p72cvL91emV0hzo= 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.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -51,8 +51,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/getkin/kin-openapi v0.125.0 h1:jyQCyf2qXS1qvs2U00xQzkGCqYPhEhZDmSmVt65fXno= -github.com/getkin/kin-openapi v0.125.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= +github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= +github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= @@ -65,14 +65,14 @@ 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-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= 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/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -96,22 +96,22 @@ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/grafana/dskit v0.0.0-20240805174438-dfa83b4ed2d3 h1:as4PmrFoYI1byS5JjsgPC7uSGTMh+SgS0ePv6hOyDGU= -github.com/grafana/dskit v0.0.0-20240805174438-dfa83b4ed2d3/go.mod h1:lcjGB6SuaZ2o44A9nD6p/tR4QXSPbzViRY520Gy6pTQ= -github.com/grafana/grafana-plugin-sdk-go v0.244.0 h1:ZZxHbiiF6QcsnlbPFyZGmzNDoTC1pLeHXUQYoskWt5c= -github.com/grafana/grafana-plugin-sdk-go v0.244.0/go.mod h1:H3FXrJMUlwocQ6UYj8Ds5I9EzRAVOcdRcgaRE3mXQqk= +github.com/grafana/dskit v0.0.0-20240827093408-28506cdffe6a h1:W8y+Tcv22oamhXX9auACKIwLu7y3XmT/v1oF30g/vbE= +github.com/grafana/dskit v0.0.0-20240827093408-28506cdffe6a/go.mod h1:wJbJeQ2ygiGuBKsur7BPPNe+3pSyHEDPtKa7IU3I8ZA= +github.com/grafana/grafana-plugin-sdk-go v0.245.0 h1:2KCKA86//O20ffL6WKzHGx5scBbdV7GyEFGnH8Hdv7M= +github.com/grafana/grafana-plugin-sdk-go v0.245.0/go.mod h1:1X8Kgo/SK91Qo1WBCKjPSKrfgjpQys1OkQsHhA78TLg= github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls= github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= -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= +github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= +github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= @@ -122,8 +122,8 @@ github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10C github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= -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/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg= +github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -141,8 +141,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -165,8 +165,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -199,12 +199,12 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= -github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= +github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= +github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= @@ -214,7 +214,6 @@ github.com/prometheus/prometheus v1.8.2-0.20221021121301-51a44e6657c3/go.mod h1: github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -234,7 +233,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -263,32 +261,32 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 h1:IVtyPth4Rs5P8wIf0mP2KVKFNTJ4paX9qQ4Hkh5gFdc= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0/go.mod h1:ImRBLMJv177/pwiLZ7tU7HDGNdBv7rS0HQ99eN/zBl8= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/contrib/propagators/jaeger v1.28.0 h1:xQ3ktSVS128JWIaN1DiPGIjcH+GsvkibIAVRWFjS9eM= -go.opentelemetry.io/contrib/propagators/jaeger v1.28.0/go.mod h1:O9HIyI2kVBrFoEwQZ0IN6PHXykGoit4mZV2aEjkTRH4= -go.opentelemetry.io/contrib/samplers/jaegerremote v0.22.0 h1:OYxqumWcd1yaV/qvCt1B7Sru9OeUNGjeXq/oldx3AGk= -go.opentelemetry.io/contrib/samplers/jaegerremote v0.22.0/go.mod h1:2tZTRqCbvx7nG57wUwd5NQpNVujOWnR84iPLllIH0Ok= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0 h1:U9ge/19g8pkNXL+0eqeWgiJAd8nSmmvbvwehqyxU/Lc= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0/go.mod h1:dmNhUi0Tl5v/3e0QNp7/3KLMvAPoHh4lMbZU319UkM0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/contrib/propagators/jaeger v1.29.0 h1:+YPiqF5rR6PqHBlmEFLPumbSP0gY0WmCGFayXRcCLvs= +go.opentelemetry.io/contrib/propagators/jaeger v1.29.0/go.mod h1:6PD7q7qquWSp3Z4HeM3e/2ipRubaY1rXZO8NIHVDZjs= +go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 h1:qKi9ntCcronqWqfuKxqrxZlZd82jXJEgGiAWH1+phxo= +go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0/go.mod h1:1kbAgQa5lgYC3rC6cE3jSxQ/Q13l33wv/WI8U+htwag= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -298,12 +296,12 @@ go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -342,22 +340,22 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= +gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= +google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -378,10 +376,10 @@ k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= +k8s.io/utils v0.0.0-20240821151609-f90d01438635 h1:2wThSvJoW/Ncn9TmQEYXRnevZXi2duqHWf5OX9S3zjI= +k8s.io/utils v0.0.0-20240821151609-f90d01438635/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/pkg/semconv/go.mod b/pkg/semconv/go.mod index 1217b154a55d4..81429a73accd5 100644 --- a/pkg/semconv/go.mod +++ b/pkg/semconv/go.mod @@ -2,7 +2,7 @@ module github.com/grafana/grafana/pkg/semconv go 1.23.0 -require go.opentelemetry.io/otel v1.28.0 +require go.opentelemetry.io/otel v1.29.0 require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/pkg/semconv/go.sum b/pkg/semconv/go.sum index 6601c18dd25f6..bf61a1563d6dd 100644 --- a/pkg/semconv/go.sum +++ b/pkg/semconv/go.sum @@ -6,7 +6,7 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/server/wire.go b/pkg/server/wire.go index d038bd0dd1330..4b2a8f9f62d0f 100644 --- a/pkg/server/wire.go +++ b/pkg/server/wire.go @@ -74,7 +74,6 @@ import ( "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/folder/folderimpl" - grafanaapiserver "github.com/grafana/grafana/pkg/services/grafana-apiserver" "github.com/grafana/grafana/pkg/services/grpcserver" grpccontext "github.com/grafana/grafana/pkg/services/grpcserver/context" "github.com/grafana/grafana/pkg/services/grpcserver/interceptors" @@ -176,8 +175,8 @@ import ( var wireBasicSet = wire.NewSet( druid.ProvideService, - legacydataservice.ProvideService, - wire.Bind(new(legacydata.RequestHandler), new(*legacydataservice.Service)), + // legacydataservice.ProvideService, + // wire.Bind(new(legacydata.RequestHandler), new(*legacydataservice.Service)), annotationsimpl.ProvideService, wire.Bind(new(annotations.Repository), new(*annotationsimpl.RepositoryImpl)), New, @@ -262,7 +261,6 @@ var wireBasicSet = wire.NewSet( tempo.ProvideService, loki.ProvideService, graphite.ProvideService, - druid.ProvideService, prometheus.ProvideService, elasticsearch.ProvideService, pyroscope.ProvideService, diff --git a/pkg/services/authn/clients/ext_jwt.go b/pkg/services/authn/clients/ext_jwt.go index f1fd557fc91a8..db7285c472980 100644 --- a/pkg/services/authn/clients/ext_jwt.go +++ b/pkg/services/authn/clients/ext_jwt.go @@ -8,7 +8,7 @@ import ( "github.com/go-jose/go-jose/v3/jwt" authlib "github.com/grafana/authlib/authn" - authlibclaims "github.com/grafana/authlib/claims" + "github.com/grafana/authlib/claims" "github.com/grafana/grafana/pkg/apimachinery/errutil" "github.com/grafana/grafana/pkg/apimachinery/identity" @@ -74,7 +74,7 @@ type ExtendedJWT struct { func (s *ExtendedJWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) { jwtToken := s.retrieveAuthenticationToken(r.HTTPRequest) - claims, err := s.accessTokenVerifier.Verify(ctx, jwtToken) + accessTokenClaims, err := s.accessTokenVerifier.Verify(ctx, jwtToken) if err != nil { return nil, errExtJWTInvalid.Errorf("failed to verify access token: %w", err) } @@ -86,10 +86,10 @@ func (s *ExtendedJWT) Authenticate(ctx context.Context, r *authn.Request) (*auth return nil, errExtJWTInvalid.Errorf("failed to verify id token: %w", err) } - return s.authenticateAsUser(idTokenClaims, claims) + return s.authenticateAsUser(*idTokenClaims, *accessTokenClaims) } - return s.authenticateAsService(claims) + return s.authenticateAsService(*accessTokenClaims) } func (s *ExtendedJWT) IsEnabled() bool { @@ -97,16 +97,16 @@ func (s *ExtendedJWT) IsEnabled() bool { } func (s *ExtendedJWT) authenticateAsUser( - idTokenClaims *authlib.Claims[authlib.IDTokenClaims], - accessTokenClaims *authlib.Claims[authlib.AccessTokenClaims], + idTokenClaims authlib.Claims[authlib.IDTokenClaims], + accessTokenClaims authlib.Claims[authlib.AccessTokenClaims], ) (*authn.Identity, error) { // Only allow id tokens signed for namespace configured for this instance. - if allowedNamespace := s.namespaceMapper(s.getDefaultOrgID()); idTokenClaims.Rest.Namespace != allowedNamespace { + if allowedNamespace := s.namespaceMapper(s.getDefaultOrgID()); !claims.NamespaceMatches(authlib.NewIdentityClaims(idTokenClaims), allowedNamespace) { return nil, errExtJWTDisallowedNamespaceClaim.Errorf("unexpected id token namespace: %s", idTokenClaims.Rest.Namespace) } // Allow access tokens with either the same namespace as the validated id token namespace or wildcard (`*`). - if !accessTokenClaims.Rest.NamespaceMatches(idTokenClaims.Rest.Namespace) { + if !claims.NamespaceMatches(authlib.NewAccessClaims(accessTokenClaims), idTokenClaims.Rest.Namespace) { return nil, errExtJWTMisMatchedNamespaceClaims.Errorf("unexpected access token namespace: %s", accessTokenClaims.Rest.Namespace) } @@ -115,7 +115,7 @@ func (s *ExtendedJWT) authenticateAsUser( return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", accessTokenClaims.Subject) } - if !authlibclaims.IsIdentityType(accessType, authlibclaims.TypeAccessPolicy) { + if !claims.IsIdentityType(accessType, claims.TypeAccessPolicy) { return nil, errExtJWTInvalid.Errorf("unexpected identity: %s", accessTokenClaims.Subject) } @@ -124,7 +124,7 @@ func (s *ExtendedJWT) authenticateAsUser( return nil, errExtJWTInvalid.Errorf("failed to parse id token subject: %w", err) } - if !authlibclaims.IsIdentityType(t, authlibclaims.TypeUser) { + if !claims.IsIdentityType(t, claims.TypeUser) { return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", idTokenClaims.Subject) } @@ -139,6 +139,8 @@ func (s *ExtendedJWT) authenticateAsUser( ID: id, Type: t, OrgID: s.getDefaultOrgID(), + AccessTokenClaims: &accessTokenClaims, + IDTokenClaims: &idTokenClaims, AuthenticatedBy: login.ExtendedJWTModule, AuthID: accessTokenClaims.Subject, AllowedKubernetesNamespace: allowedKubernetesNamespace, @@ -151,19 +153,19 @@ func (s *ExtendedJWT) authenticateAsUser( }}, nil } -func (s *ExtendedJWT) authenticateAsService(claims *authlib.Claims[authlib.AccessTokenClaims]) (*authn.Identity, error) { +func (s *ExtendedJWT) authenticateAsService(accessTokenClaims authlib.Claims[authlib.AccessTokenClaims]) (*authn.Identity, error) { // Allow access tokens with that has a wildcard namespace or a namespace matching this instance. - if allowedNamespace := s.namespaceMapper(s.getDefaultOrgID()); !claims.Rest.NamespaceMatches(allowedNamespace) { - return nil, errExtJWTDisallowedNamespaceClaim.Errorf("unexpected access token namespace: %s", claims.Rest.Namespace) + if allowedNamespace := s.namespaceMapper(s.getDefaultOrgID()); !claims.NamespaceMatches(authlib.NewAccessClaims(accessTokenClaims), allowedNamespace) { + return nil, errExtJWTDisallowedNamespaceClaim.Errorf("unexpected access token namespace: %s", accessTokenClaims.Rest.Namespace) } - t, id, err := identity.ParseTypeAndID(claims.Subject) + t, id, err := identity.ParseTypeAndID(accessTokenClaims.Subject) if err != nil { return nil, fmt.Errorf("failed to parse access token subject: %w", err) } - if !authlibclaims.IsIdentityType(t, authlibclaims.TypeAccessPolicy) { - return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", claims.Subject) + if !claims.IsIdentityType(t, claims.TypeAccessPolicy) { + return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", accessTokenClaims.Subject) } return &authn.Identity{ @@ -171,13 +173,15 @@ func (s *ExtendedJWT) authenticateAsService(claims *authlib.Claims[authlib.Acces UID: id, Type: t, OrgID: s.getDefaultOrgID(), + AccessTokenClaims: &accessTokenClaims, + IDTokenClaims: nil, AuthenticatedBy: login.ExtendedJWTModule, - AuthID: claims.Subject, - AllowedKubernetesNamespace: claims.Rest.Namespace, + AuthID: accessTokenClaims.Subject, + AllowedKubernetesNamespace: accessTokenClaims.Rest.Namespace, ClientParams: authn.ClientParams{ SyncPermissions: true, FetchPermissionsParams: authn.FetchPermissionsParams{ - Roles: claims.Rest.Permissions, + Roles: accessTokenClaims.Rest.Permissions, }, FetchSyncedUser: false, }, diff --git a/pkg/services/authn/identity.go b/pkg/services/authn/identity.go index 4a0da892d8de0..3014c1148f556 100644 --- a/pkg/services/authn/identity.go +++ b/pkg/services/authn/identity.go @@ -72,8 +72,9 @@ type Identity struct { // Permissions is the list of permissions the entity has. Permissions map[int64]map[string][]string // IDToken is a signed token representing the identity that can be forwarded to plugins and external services. - IDToken string - IDTokenClaims *authn.Claims[authn.IDTokenClaims] + IDToken string + IDTokenClaims *authn.Claims[authn.IDTokenClaims] + AccessTokenClaims *authn.Claims[authn.AccessTokenClaims] } // Access implements claims.AuthInfo. diff --git a/pkg/services/authz/client.go b/pkg/services/authz/client.go index 69f68f5cf947d..eb22e20de87d5 100644 --- a/pkg/services/authz/client.go +++ b/pkg/services/authz/client.go @@ -8,6 +8,7 @@ import ( authnlib "github.com/grafana/authlib/authn" authzlib "github.com/grafana/authlib/authz" authzv1 "github.com/grafana/authlib/authz/proto/v1" + "github.com/grafana/authlib/claims" grpcAuth "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -105,7 +106,7 @@ func newInProcLegacyClient(server *legacyServer) (authzlib.MultiTenantClient, er &authzlib.MultiTenantClientConfig{}, authzlib.WithGrpcConnectionLCOption(channel), // nolint:staticcheck - authzlib.WithNamespaceFormatterLCOption(authnlib.OnPremNamespaceFormatter), + authzlib.WithNamespaceFormatterLCOption(claims.OrgNamespaceFormatter), authzlib.WithDisableAccessTokenLCOption(), ) } @@ -129,7 +130,7 @@ func newGrpcLegacyClient(address string) (authzlib.MultiTenantClient, error) { grpc.WithStreamInterceptor(clientInterceptor.StreamClientInterceptor), ), // nolint:staticcheck - authzlib.WithNamespaceFormatterLCOption(authnlib.OnPremNamespaceFormatter), + authzlib.WithNamespaceFormatterLCOption(claims.OrgNamespaceFormatter), // TODO(drclau): remove this once we have access token support on-prem authzlib.WithDisableAccessTokenLCOption(), ) diff --git a/pkg/services/contexthandler/contexthandler.go b/pkg/services/contexthandler/contexthandler.go index 278461f232a3e..a30f560b41407 100644 --- a/pkg/services/contexthandler/contexthandler.go +++ b/pkg/services/contexthandler/contexthandler.go @@ -225,16 +225,3 @@ func AuthHTTPHeaderListFromContext(c context.Context) *AuthHTTPHeaderList { } return nil } - -func (h *ContextHandler) hasAccessTokenExpired(token *models.UserAuth) bool { - if token.OAuthExpiry.IsZero() { - return false - } - - getTime := h.GetTime - if getTime == nil { - getTime = time.Now - } - - return token.OAuthExpiry.Round(0).Add(-oauthtoken.ExpiryDelta).Before(getTime()) -} diff --git a/pkg/services/featuremgmt/models.go b/pkg/services/featuremgmt/models.go index 6260547585ba3..c4b6d4a091c50 100644 --- a/pkg/services/featuremgmt/models.go +++ b/pkg/services/featuremgmt/models.go @@ -130,6 +130,8 @@ type FeatureFlag struct { // The server must be initialized with the value RequiresRestart bool `json:"requiresRestart,omitempty"` + + FlagPublicDashboards bool `json:"flagPublicDashboards,omitempty"` // flag for public dashboards } type FeatureToggleWebhookPayload struct { diff --git a/pkg/services/ldap/testing.go b/pkg/services/ldap/testing.go index 292b8be7d8a8f..a31951c7afb49 100644 --- a/pkg/services/ldap/testing.go +++ b/pkg/services/ldap/testing.go @@ -55,8 +55,10 @@ func (c *MockConnection) UnauthenticatedBind(username string) error { } // Close mocks Close connection function -func (c *MockConnection) Close() { +func (c *MockConnection) Close() error { c.CloseCalled = true + + return nil } func (c *MockConnection) setSearchResult(result *ldap.SearchResult) { diff --git a/pkg/services/pluginsintegration/plugins_integration_test.go b/pkg/services/pluginsintegration/plugins_integration_test.go index 3166d7e225e1d..23dc547f3bbc3 100644 --- a/pkg/services/pluginsintegration/plugins_integration_test.go +++ b/pkg/services/pluginsintegration/plugins_integration_test.go @@ -95,23 +95,10 @@ func TestIntegrationPluginManager(t *testing.T) { graf := grafanads.ProvideService(sv2, nil) pyroscope := pyroscope.ProvideService(hcp) parca := parca.ProvideService(hcp) - druid := druid.ProvideService(hcp) + dr := druid.ProvideService(hcp) + coreRegistry := coreplugin.ProvideCoreRegistry(tracing.InitializeTracerForTest(), am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf, pyroscope, parca, dr) - coreRegistry := coreplugin.ProvideCoreRegistry(am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf, phlare, parca, druid) - - pCfg, err := config.ProvideConfig(setting.ProvideProvider(cfg), cfg, featuremgmt.WithFeatures()) - require.NoError(t, err) - reg := registry.ProvideService() - lic := plicensing.ProvideLicensing(cfg, &licensing.OSSLicensingService{Cfg: cfg}) - angularInspector, err := angularinspector.NewStaticInspector() - require.NoError(t, err) - l := loader.ProvideService(pCfg, lic, signature.NewUnsignedAuthorizer(pCfg), - reg, provider.ProvideService(coreRegistry), finder.NewLocalFinder(pCfg.DevMode), fakes.NewFakeRoleRegistry(), - assetpath.ProvideService(pluginscdn.ProvideService(pCfg)), signature.ProvideService(statickey.New()), - angularInspector, &fakes.FakeOauthService{}) - srcs := sources.ProvideService(cfg, pCfg) - ps, err := store.ProvideService(reg, srcs, l) - require.NoError(t, err) + testCtx := CreateIntegrationTestCtx(t, cfg, coreRegistry) ctx := context.Background() verifyCorePluginCatalogue(t, ctx, testCtx.PluginStore) @@ -206,7 +193,6 @@ func verifyCorePluginCatalogue(t *testing.T, ctx context.Context, ps *pluginstor "zipkin": {}, "grafana-pyroscope-datasource": {}, "parca": {}, - "druid": {}, } expApps := map[string]struct{}{ diff --git a/pkg/storage/unified/apistore/go.mod b/pkg/storage/unified/apistore/go.mod index cc553c54044b9..566c362bda8a3 100644 --- a/pkg/storage/unified/apistore/go.mod +++ b/pkg/storage/unified/apistore/go.mod @@ -3,13 +3,13 @@ module github.com/grafana/grafana/pkg/storage/unified/apistore go 1.23.0 require ( - github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db + github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da github.com/grafana/grafana/pkg/apiserver v0.0.0-20240821155123-6891eb1d35da github.com/grafana/grafana/pkg/storage/unified/resource v0.0.0-20240821161612-71f0dae39e9d github.com/stretchr/testify v1.9.0 gocloud.dev v0.39.0 - google.golang.org/grpc v1.65.0 + google.golang.org/grpc v1.66.0 k8s.io/apimachinery v0.31.0 k8s.io/apiserver v0.31.0 k8s.io/client-go v0.31.0 @@ -19,13 +19,13 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/bufbuild/protocompile v0.4.0 // indirect + github.com/bufbuild/protocompile v0.14.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fullstorydev/grpchan v1.1.1 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect @@ -33,21 +33,23 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect - github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/jhump/protoreflect v1.15.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/jhump/protoreflect v1.16.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.9 // indirect @@ -58,24 +60,24 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.20.0 // indirect + github.com/prometheus/client_golang v1.20.2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.57.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect - go.etcd.io/etcd/api/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/v3 v3.5.14 // indirect + go.etcd.io/etcd/api/v3 v3.5.15 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect + go.etcd.io/etcd/client/v3 v3.5.15 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect @@ -88,17 +90,17 @@ require ( golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect - google.golang.org/api v0.191.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect + google.golang.org/api v0.195.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.31.0 // indirect k8s.io/component-base v0.31.0 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 // indirect + k8s.io/utils v0.0.0-20240821151609-f90d01438635 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/pkg/storage/unified/apistore/go.sum b/pkg/storage/unified/apistore/go.sum index f779d2b72816a..cc8aa706ab77a 100644 --- a/pkg/storage/unified/apistore/go.sum +++ b/pkg/storage/unified/apistore/go.sum @@ -1,8 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= -cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.8.1 h1:QZW9FjC5lZzN864p13YxvAtGUlQ+KgRL+8Sg45Z6vxo= -cloud.google.com/go/auth v0.8.1/go.mod h1:qGVp/Y3kDRSDZ5gFD/XPUfYQ9xW1iI7q8RIRoCyBbJc= +cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ= +cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc= +cloud.google.com/go/auth v0.9.1 h1:+pMtLEV2k0AXKvs/tGZojuj6QaioxfUjOpMsG5Gtx+w= +cloud.google.com/go/auth v0.9.1/go.mod h1:Sw8ocT5mhhXxFklyhT12Eiy0ed6tTrPMCJjSI8KhYLk= cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= cloud.google.com/go/compute v1.23.4 h1:EBT9Nw4q3zyE7G45Wvv3MzolIrCJEuHys5muLY0wvAw= @@ -58,8 +58,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -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/bufbuild/protocompile v0.14.0 h1:z3DW4IvXE5G/uTOnSQn+qwQQxvhckkTWLS/0No/o7KU= +github.com/bufbuild/protocompile v0.14.0/go.mod h1:N6J1NYzkspJo3ZwyL4Xjvli86XOj1xq4qAasUFxGups= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -78,8 +78,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 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= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -100,8 +100,8 @@ 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-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -129,8 +129,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= 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= @@ -146,8 +146,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -159,12 +159,12 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db h1:z++X4DdoX+aNlZNT1ZY4cykiFay4+f077pa0AG48SGg= -github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db/go.mod h1:ptt910z9KFfpVSIbSbXvTRR7tS19mxD7EtmVbbJi/WE= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 h1:SU+p1ck8037cz6F8W38PIL9MzRb6YMeNqc7+GHDuqiU= +github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2/go.mod h1:PFzXbCrn0GIpN4KwT6NP1l5Z1CPLfmKHnYx8rZzQcyY= +github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2 h1:YTF1Y1BYCDkD7ssmbhzRqXlxevsYpXPmOnoO8qbOue8= +github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da h1:2E3c/I3ayAy4Z1GwIPqXNZcpUccRapE1aBXA1ho4g7o= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da/go.mod h1:p09fvU5ujNL/Ig8HB7g4f+S0zyYbQq3x/f0jA4ujVOM= github.com/grafana/grafana/pkg/apiserver v0.0.0-20240821155123-6891eb1d35da h1:xQMb8cRZYu7D0IO9q/lB7qFQpLGAoPUnCase1CGHrXY= @@ -179,14 +179,14 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= -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/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg= +github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= @@ -230,16 +230,16 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= -github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= +github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= +github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= @@ -273,14 +273,14 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= +go.etcd.io/etcd/api/v3 v3.5.15 h1:3KpLJir1ZEBrYuV2v+Twaa/e2MdDCEZ/70H+lzEiwsk= +go.etcd.io/etcd/api/v3 v3.5.15/go.mod h1:N9EhGzXq58WuMllgH9ZvnEr7SI9pS0k0+DHZezGp7jM= +go.etcd.io/etcd/client/pkg/v3 v3.5.15 h1:fo0HpWz/KlHGMCC+YejpiCmyWDEuIpnTDzpJLB5fWlA= +go.etcd.io/etcd/client/pkg/v3 v3.5.15/go.mod h1:mXDI4NAOwEiszrHCb0aqfAYNCrZP4e9hRca3d1YK8EU= go.etcd.io/etcd/client/v2 v2.305.13 h1:RWfV1SX5jTU0lbCvpVQe3iPQeAHETWdOTb6pxhd77C8= go.etcd.io/etcd/client/v2 v2.305.13/go.mod h1:iQnL7fepbiomdXMb3om1rHq96htNNGv2sJkEcZGDRRg= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= +go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4= +go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU= go.etcd.io/etcd/pkg/v3 v3.5.13 h1:st9bDWNsKkBNpP4PR1MvM/9NqUPfvYZx/YXegsYEH8M= go.etcd.io/etcd/pkg/v3 v3.5.13/go.mod h1:N+4PLrp7agI/Viy+dUYpX7iRtSPvKq+w8Y14d1vX+m0= go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA= @@ -289,22 +289,22 @@ go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -402,27 +402,27 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/api v0.191.0 h1:cJcF09Z+4HAB2t5qTQM1ZtfL/PemsLFkcFG67qq2afk= -google.golang.org/api v0.191.0/go.mod h1:tD5dsFGxFza0hnQveGfVk9QQYKcfp+VzgRqyXFxE0+E= +google.golang.org/api v0.195.0 h1:Ude4N8FvTKnnQJHU48RFI40jOBgIrL8Zqr3/QeST6yU= +google.golang.org/api v0.195.0/go.mod h1:DOGRWuv3P8TU8Lnz7uQc4hyNqrBpMtD9ppW3wBJurgc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c h1:TYOEhrQMrNDTAd2rX9m+WgGr8Ku6YNuj1D7OX6rWSok= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c/go.mod h1:2rC5OendXvZ8wGEo/cSLheztrZDZaSoHanUcd1xtZnw= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -430,8 +430,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= +google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -477,10 +477,10 @@ k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI= +k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= +k8s.io/utils v0.0.0-20240821151609-f90d01438635 h1:2wThSvJoW/Ncn9TmQEYXRnevZXi2duqHWf5OX9S3zjI= +k8s.io/utils v0.0.0-20240821151609-f90d01438635/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/pkg/storage/unified/resource/go.mod b/pkg/storage/unified/resource/go.mod index 360723aab76dd..1f690404216b0 100644 --- a/pkg/storage/unified/resource/go.mod +++ b/pkg/storage/unified/resource/go.mod @@ -4,22 +4,22 @@ go 1.23.0 require ( github.com/fullstorydev/grpchan v1.1.1 - github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db - github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db + github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 + github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 - github.com/prometheus/client_golang v1.20.0 + github.com/prometheus/client_golang v1.20.2 github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/otel/trace v1.28.0 + go.opentelemetry.io/otel/trace v1.29.0 gocloud.dev v0.39.0 - google.golang.org/grpc v1.65.0 + google.golang.org/grpc v1.66.0 google.golang.org/protobuf v1.34.2 k8s.io/apimachinery v0.31.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bufbuild/protocompile v0.4.0 // indirect + github.com/bufbuild/protocompile v0.14.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect @@ -30,7 +30,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect - github.com/jhump/protoreflect v1.15.1 // indirect + github.com/jhump/protoreflect v1.16.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -38,25 +38,28 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.57.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/x448/float16 v0.8.4 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect golang.org/x/crypto v0.26.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect - google.golang.org/api v0.191.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect + google.golang.org/api v0.195.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiserver v0.31.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + k8s.io/utils v0.0.0-20240821151609-f90d01438635 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/pkg/storage/unified/resource/go.sum b/pkg/storage/unified/resource/go.sum index 02d4c05722a9c..82ec4d611ab81 100644 --- a/pkg/storage/unified/resource/go.sum +++ b/pkg/storage/unified/resource/go.sum @@ -1,8 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= -cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.8.1 h1:QZW9FjC5lZzN864p13YxvAtGUlQ+KgRL+8Sg45Z6vxo= -cloud.google.com/go/auth v0.8.1/go.mod h1:qGVp/Y3kDRSDZ5gFD/XPUfYQ9xW1iI7q8RIRoCyBbJc= +cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ= +cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc= +cloud.google.com/go/auth v0.9.1 h1:+pMtLEV2k0AXKvs/tGZojuj6QaioxfUjOpMsG5Gtx+w= +cloud.google.com/go/auth v0.9.1/go.mod h1:Sw8ocT5mhhXxFklyhT12Eiy0ed6tTrPMCJjSI8KhYLk= cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= cloud.google.com/go/compute v1.23.4 h1:EBT9Nw4q3zyE7G45Wvv3MzolIrCJEuHys5muLY0wvAw= @@ -55,8 +55,8 @@ github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -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/bufbuild/protocompile v0.14.0 h1:z3DW4IvXE5G/uTOnSQn+qwQQxvhckkTWLS/0No/o7KU= +github.com/bufbuild/protocompile v0.14.0/go.mod h1:N6J1NYzkspJo3ZwyL4Xjvli86XOj1xq4qAasUFxGups= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -128,10 +128,10 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= -github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db h1:z++X4DdoX+aNlZNT1ZY4cykiFay4+f077pa0AG48SGg= -github.com/grafana/authlib v0.0.0-20240814074258-eae7d47f01db/go.mod h1:ptt910z9KFfpVSIbSbXvTRR7tS19mxD7EtmVbbJi/WE= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db h1:mDk0bwRV6rDrLSmKXftcPf9kLA9uH6EvxJvzpPW9bso= -github.com/grafana/authlib/claims v0.0.0-20240814074258-eae7d47f01db/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= +github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 h1:SU+p1ck8037cz6F8W38PIL9MzRb6YMeNqc7+GHDuqiU= +github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2/go.mod h1:PFzXbCrn0GIpN4KwT6NP1l5Z1CPLfmKHnYx8rZzQcyY= +github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2 h1:YTF1Y1BYCDkD7ssmbhzRqXlxevsYpXPmOnoO8qbOue8= +github.com/grafana/authlib/claims v0.0.0-20240828122726-9edfcbea43e2/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e h1:3vNpomyzv714Hgls5vn+fC0vgv8wUOSHepUl7PB5nUs= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808164224-787abccfbc9e/go.mod h1:ORVFiW/KNRY52lNjkGwnFWCxNVfE97bJG2jr2fetq0I= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= @@ -140,8 +140,8 @@ github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSl github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= -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/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg= +github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -169,13 +169,13 @@ github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTK github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= -github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= +github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= +github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= @@ -200,16 +200,16 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= gocloud.dev v0.39.0 h1:EYABYGhAalPUaMrbSKOr5lejxoxvXj99nE8XFtsDgds= gocloud.dev v0.39.0/go.mod h1:drz+VyYNBvrMTW0KZiBAYEdl8lbNZx+OQ7oQvdrFmSQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -301,27 +301,27 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/api v0.191.0 h1:cJcF09Z+4HAB2t5qTQM1ZtfL/PemsLFkcFG67qq2afk= -google.golang.org/api v0.191.0/go.mod h1:tD5dsFGxFza0hnQveGfVk9QQYKcfp+VzgRqyXFxE0+E= +google.golang.org/api v0.195.0 h1:Ude4N8FvTKnnQJHU48RFI40jOBgIrL8Zqr3/QeST6yU= +google.golang.org/api v0.195.0/go.mod h1:DOGRWuv3P8TU8Lnz7uQc4hyNqrBpMtD9ppW3wBJurgc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM= -google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c h1:TYOEhrQMrNDTAd2rX9m+WgGr8Ku6YNuj1D7OX6rWSok= +google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c/go.mod h1:2rC5OendXvZ8wGEo/cSLheztrZDZaSoHanUcd1xtZnw= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= +google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -356,8 +356,8 @@ k8s.io/apiserver v0.31.0 h1:p+2dgJjy+bk+B1Csz+mc2wl5gHwvNkC9QJV+w55LVrY= k8s.io/apiserver v0.31.0/go.mod h1:KI9ox5Yu902iBnnyMmy7ajonhKnkeZYJhTZ/YI+WEMk= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240821151609-f90d01438635 h1:2wThSvJoW/Ncn9TmQEYXRnevZXi2duqHWf5OX9S3zjI= +k8s.io/utils v0.0.0-20240821151609-f90d01438635/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/pkg/tsdb/cloudwatch/models/api.go b/pkg/tsdb/cloudwatch/models/api.go index 0a701bd94e402..236e0d189ed68 100644 --- a/pkg/tsdb/cloudwatch/models/api.go +++ b/pkg/tsdb/cloudwatch/models/api.go @@ -72,19 +72,7 @@ type EC2APIProvider interface { DescribeInstancesPagesWithContext(ctx context.Context, in *ec2.DescribeInstancesInput, fn func(*ec2.DescribeInstancesOutput, bool) bool, opts ...request.Option) error } -type CloudWatchLogsAPIProvider interface { - DescribeLogGroups(*cloudwatchlogs.DescribeLogGroupsInput) (*cloudwatchlogs.DescribeLogGroupsOutput, error) -} - type OAMClientProvider interface { ListSinks(*oam.ListSinksInput) (*oam.ListSinksOutput, error) ListAttachedLinks(*oam.ListAttachedLinksInput) (*oam.ListAttachedLinksOutput, error) } - -type LogGroupsProvider interface { - GetLogGroups(request resources.LogGroupsRequest) ([]resources.ResourceResponse[resources.LogGroup], error) -} - -type AccountsProvider interface { - GetAccountsForCurrentUserOrRole() ([]resources.ResourceResponse[resources.Account], error) -} diff --git a/pkg/tsdb/cloudwatch/services/logs.go b/pkg/tsdb/cloudwatch/services/logs.go deleted file mode 100644 index 64658bc51df0e..0000000000000 --- a/pkg/tsdb/cloudwatch/services/logs.go +++ /dev/null @@ -1,53 +0,0 @@ -package services - -import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/cloudwatchlogs" - "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" - "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" - "github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils" -) - -type LogGroupsService struct { - logGroupsAPI models.CloudWatchLogsAPIProvider - isCrossAccountEnabled bool -} - -func NewLogGroupsService(logsClient models.CloudWatchLogsAPIProvider, isCrossAccountEnabled bool) models.LogGroupsProvider { - return &LogGroupsService{logGroupsAPI: logsClient, isCrossAccountEnabled: isCrossAccountEnabled} -} - -func (s *LogGroupsService) GetLogGroups(req resources.LogGroupsRequest) ([]resources.ResourceResponse[resources.LogGroup], error) { - input := &cloudwatchlogs.DescribeLogGroupsInput{ - Limit: aws.Int64(req.Limit), - LogGroupNamePrefix: req.LogGroupNamePrefix, - } - - if s.isCrossAccountEnabled && req.AccountId != nil { - input.IncludeLinkedAccounts = aws.Bool(true) - if req.LogGroupNamePattern != nil { - input.LogGroupNamePrefix = req.LogGroupNamePattern - } - if !req.IsTargetingAllAccounts() { - // TODO: accept more than one account id in search - input.AccountIdentifiers = []*string{req.AccountId} - } - } - response, err := s.logGroupsAPI.DescribeLogGroups(input) - if err != nil || response == nil { - return nil, err - } - - var result []resources.ResourceResponse[resources.LogGroup] - for _, logGroup := range response.LogGroups { - result = append(result, resources.ResourceResponse[resources.LogGroup]{ - Value: resources.LogGroup{ - Arn: *logGroup.Arn, - Name: *logGroup.LogGroupName, - }, - AccountId: utils.Pointer(getAccountId(*logGroup.Arn)), - }) - } - - return result, nil -} diff --git a/pkg/tsdb/cloudwatch/services/logs_test.go b/pkg/tsdb/cloudwatch/services/logs_test.go deleted file mode 100644 index a1b81a8d094eb..0000000000000 --- a/pkg/tsdb/cloudwatch/services/logs_test.go +++ /dev/null @@ -1,200 +0,0 @@ -package services - -import ( - "fmt" - "testing" - - "github.com/aws/aws-sdk-go/service/cloudwatchlogs" - "github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" - "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources" - "github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -func Test_GetLogGroups(t *testing.T) { - t.Run("Should map log groups response", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return( - &cloudwatchlogs.DescribeLogGroupsOutput{ - LogGroups: []*cloudwatchlogs.LogGroup{ - {Arn: utils.Pointer("arn:aws:logs:us-east-1:111:log-group:group_a"), LogGroupName: utils.Pointer("group_a")}, - {Arn: utils.Pointer("arn:aws:logs:us-east-1:222:log-group:group_b"), LogGroupName: utils.Pointer("group_b")}, - {Arn: utils.Pointer("arn:aws:logs:us-east-1:333:log-group:group_c"), LogGroupName: utils.Pointer("group_c")}, - }, - }, nil) - service := NewLogGroupsService(mockLogsAPI, false) - - resp, err := service.GetLogGroups(resources.LogGroupsRequest{}) - - assert.NoError(t, err) - assert.Equal(t, []resources.ResourceResponse[resources.LogGroup]{ - { - AccountId: utils.Pointer("111"), - Value: resources.LogGroup{Arn: "arn:aws:logs:us-east-1:111:log-group:group_a", Name: "group_a"}, - }, - { - AccountId: utils.Pointer("222"), - Value: resources.LogGroup{Arn: "arn:aws:logs:us-east-1:222:log-group:group_b", Name: "group_b"}, - }, - { - AccountId: utils.Pointer("333"), - Value: resources.LogGroup{Arn: "arn:aws:logs:us-east-1:333:log-group:group_c", Name: "group_c"}, - }, - }, resp) - }) - - t.Run("Should only use LogGroupNamePrefix even if LogGroupNamePattern passed in resource call", func(t *testing.T) { - // TODO: use LogGroupNamePattern when we have accounted for its behavior, still a little unexpected at the moment - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) - service := NewLogGroupsService(mockLogsAPI, false) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{ - Limit: 0, - LogGroupNamePrefix: utils.Pointer("test"), - }) - - assert.NoError(t, err) - mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ - Limit: utils.Pointer(int64(0)), - LogGroupNamePrefix: utils.Pointer("test"), - }) - }) - - t.Run("Should call api without LogGroupNamePrefix nor LogGroupNamePattern if not passed in resource call", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) - service := NewLogGroupsService(mockLogsAPI, false) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{}) - - assert.NoError(t, err) - mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ - Limit: utils.Pointer(int64(0)), - }) - }) - - t.Run("Should return an error when API returns error", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, - fmt.Errorf("some error")) - service := NewLogGroupsService(mockLogsAPI, false) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{}) - - assert.Error(t, err) - assert.Equal(t, "some error", err.Error()) - }) -} - -func Test_GetLogGroups_crossAccountQuerying(t *testing.T) { - t.Run("Should not includeLinkedAccounts or accountId if isCrossAccountEnabled is set to false", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) - service := NewLogGroupsService(mockLogsAPI, false) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{ - ResourceRequest: resources.ResourceRequest{AccountId: utils.Pointer("accountId")}, - LogGroupNamePrefix: utils.Pointer("prefix"), - }) - - assert.NoError(t, err) - mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ - Limit: utils.Pointer(int64(0)), - LogGroupNamePrefix: utils.Pointer("prefix"), - }) - }) - - t.Run("Should replace LogGroupNamePrefix if LogGroupNamePattern passed in resource call", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) - service := NewLogGroupsService(mockLogsAPI, true) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{ - ResourceRequest: resources.ResourceRequest{AccountId: utils.Pointer("accountId")}, - LogGroupNamePrefix: utils.Pointer("prefix"), - LogGroupNamePattern: utils.Pointer("pattern"), - }) - - assert.NoError(t, err) - mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ - AccountIdentifiers: []*string{utils.Pointer("accountId")}, - Limit: utils.Pointer(int64(0)), - LogGroupNamePrefix: utils.Pointer("pattern"), - IncludeLinkedAccounts: utils.Pointer(true), - }) - }) - - t.Run("Should includeLinkedAccounts,and accountId if isCrossAccountEnabled is set to true", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) - service := NewLogGroupsService(mockLogsAPI, true) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{ - ResourceRequest: resources.ResourceRequest{AccountId: utils.Pointer("accountId")}, - }) - - assert.NoError(t, err) - mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ - Limit: utils.Pointer(int64(0)), - IncludeLinkedAccounts: utils.Pointer(true), - AccountIdentifiers: []*string{utils.Pointer("accountId")}, - }) - }) - - t.Run("Should should not override prefix is there is no logGroupNamePattern", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) - service := NewLogGroupsService(mockLogsAPI, true) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{ - ResourceRequest: resources.ResourceRequest{AccountId: utils.Pointer("accountId")}, - LogGroupNamePrefix: utils.Pointer("prefix"), - }) - assert.NoError(t, err) - mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ - AccountIdentifiers: []*string{utils.Pointer("accountId")}, - Limit: utils.Pointer(int64(0)), - LogGroupNamePrefix: utils.Pointer("prefix"), - IncludeLinkedAccounts: utils.Pointer(true), - }) - }) - - t.Run("Should not includeLinkedAccounts, or accountId if accountId is nil", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) - service := NewLogGroupsService(mockLogsAPI, true) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{ - LogGroupNamePrefix: utils.Pointer("prefix"), - }) - - assert.NoError(t, err) - mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ - Limit: utils.Pointer(int64(0)), - LogGroupNamePrefix: utils.Pointer("prefix"), - }) - }) - - t.Run("Should should not override prefix is there is no logGroupNamePattern", func(t *testing.T) { - mockLogsAPI := &mocks.LogsAPI{} - mockLogsAPI.On("DescribeLogGroups", mock.Anything).Return(&cloudwatchlogs.DescribeLogGroupsOutput{}, nil) - service := NewLogGroupsService(mockLogsAPI, true) - - _, err := service.GetLogGroups(resources.LogGroupsRequest{ - ResourceRequest: resources.ResourceRequest{ - AccountId: utils.Pointer("accountId"), - }, - LogGroupNamePrefix: utils.Pointer("prefix"), - }) - - assert.NoError(t, err) - mockLogsAPI.AssertCalled(t, "DescribeLogGroups", &cloudwatchlogs.DescribeLogGroupsInput{ - AccountIdentifiers: []*string{utils.Pointer("accountId")}, - IncludeLinkedAccounts: utils.Pointer(true), - Limit: utils.Pointer(int64(0)), - LogGroupNamePrefix: utils.Pointer("prefix"), - }) - }) -} diff --git a/pkg/tsdb/druid/druid.go b/pkg/tsdb/druid/druid.go index c8dac6f206af9..30b2ae4bc336e 100644 --- a/pkg/tsdb/druid/druid.go +++ b/pkg/tsdb/druid/druid.go @@ -78,7 +78,7 @@ func (s *druidInstanceSettings) Dispose() { s.client.Close() } -func newDataSourceInstance(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { +func newDataSourceInstance(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { data, err := simplejson.NewJson(settings.JSONData) if err != nil { return &druidInstanceSettings{}, err @@ -189,6 +189,10 @@ func (ds *Service) CallResource(ctx context.Context, req *backend.CallResourceRe Status: code, } resp.Body, err = json.Marshal(body) + if err != nil { + resp.Body = []byte("Error marshalling response") + resp.Status = 500 + } sender.Send(resp) return nil } diff --git a/pkg/util/xorm/go.mod b/pkg/util/xorm/go.mod index 45b2e78666ad2..0980eb6993491 100644 --- a/pkg/util/xorm/go.mod +++ b/pkg/util/xorm/go.mod @@ -5,7 +5,7 @@ go 1.21.10 require ( github.com/mattn/go-sqlite3 v1.14.22 github.com/stretchr/testify v1.9.0 - xorm.io/builder v0.3.6 + xorm.io/builder v0.3.13 xorm.io/core v0.7.3 ) diff --git a/pkg/util/xorm/go.sum b/pkg/util/xorm/go.sum index 060ce3a658dc1..6afb0e24030dc 100644 --- a/pkg/util/xorm/go.sum +++ b/pkg/util/xorm/go.sum @@ -1,5 +1,7 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= +gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -7,8 +9,6 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -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/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -41,7 +41,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8= -xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= +xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo= +xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= xorm.io/core v0.7.3 h1:W8ws1PlrnkS1CZU1YWaYLMQcQilwAmQXU0BJDJon+H0= xorm.io/core v0.7.3/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= diff --git a/public/app/core/components/Page/usePageTitle.ts b/public/app/core/components/Page/usePageTitle.ts index 42e548cdcc206..53a7e147ac2e1 100644 --- a/public/app/core/components/Page/usePageTitle.ts +++ b/public/app/core/components/Page/usePageTitle.ts @@ -1,16 +1,16 @@ -import {useEffect} from 'react'; +import { useEffect } from 'react'; -import {NavModel, NavModelItem} from '@grafana/data'; -import {FnGlobalState} from 'app/core/reducers/fn-slice'; -import {HOME_NAV_ID} from 'app/core/reducers/navModel'; -import {StoreState, useSelector} from 'app/types'; +import { NavModel, NavModelItem } from '@grafana/data'; +import { FnGlobalState } from 'app/core/reducers/fn-slice'; +import { HOME_NAV_ID } from 'app/core/reducers/navModel'; +import { useSelector } from 'app/types'; -import {Branding} from '../Branding/Branding'; -import {buildBreadcrumbs} from '../Breadcrumbs/utils'; +import { Branding } from '../Branding/Branding'; +import { buildBreadcrumbs } from '../Breadcrumbs/utils'; export function usePageTitle(navModel?: NavModel, pageNav?: NavModelItem) { const homeNav = useSelector((state) => state.navIndex)[HOME_NAV_ID]; - const { FNDashboard, pageTitle } = useSelector((state) => state.fnGlobalState); + const { FNDashboard, pageTitle } = useSelector((state) => state.fnGlobalState); useEffect(() => { const sectionNav = (navModel?.node !== navModel?.main ? navModel?.node : navModel?.main) ?? { text: 'Grafana' }; @@ -21,6 +21,6 @@ export function usePageTitle(navModel?: NavModel, pageNav?: NavModelItem) { // Override `Home` with the custom brand title parts[parts.length - 1] = Branding.AppTitle; - document.title = !FNDashboard ? parts.join(' - ') : pageTitle ? pageTitle : 'FluxNinja'; + document.title = !FNDashboard ? parts.join(' - ') : pageTitle ? pageTitle : 'CodeRabbit'; }, [FNDashboard, homeNav, navModel, pageNav, pageTitle]); } diff --git a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx index 24734996ff325..12e351ff80443 100644 --- a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx +++ b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx @@ -1,5 +1,5 @@ import { isEqual, uniqBy } from 'lodash'; -import React, { CSSProperties, FC, useEffect, useRef } from 'react'; +import { CSSProperties, FC, useEffect, useRef } from 'react'; // eslint-disable-next-line no-restricted-imports import { useDispatch, useSelector } from 'react-redux'; diff --git a/public/app/core/reducers/fn-slice.ts b/public/app/core/reducers/fn-slice.ts index a710dc5c714a1..0965ba40ebde3 100644 --- a/public/app/core/reducers/fn-slice.ts +++ b/public/app/core/reducers/fn-slice.ts @@ -1,4 +1,4 @@ -import { createSlice, PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit'; +import { createSlice, PayloadAction, SliceCaseReducers, SliceSelectors } from '@reduxjs/toolkit'; import { GrafanaThemeType, TimeRange } from '@grafana/data'; @@ -81,7 +81,7 @@ const reducers: SliceCaseReducers = { }, }; -const fnSlice = createSlice, string>({ +const fnSlice = createSlice, string, SliceSelectors>({ name: FN_STATE_KEY, initialState: INITIAL_FN_STATE, reducers, diff --git a/public/app/features/alerting/unified/mocks.ts b/public/app/features/alerting/unified/mocks.ts index e6941c2665612..699252137db80 100644 --- a/public/app/features/alerting/unified/mocks.ts +++ b/public/app/features/alerting/unified/mocks.ts @@ -65,7 +65,6 @@ import { parsePromQLStyleMatcherLooseSafe } from './utils/matchers'; let nextDataSourceId = 1; - export function mockDataSource( partial: Partial> = {}, meta: Partial = {} @@ -709,11 +708,8 @@ export const grantUserRole = (role: string) => { jest.spyOn(contextSrv, 'hasRole').mockReturnValue(true); }; -export function mockUnifiedAlertingStore(unifiedAlerting?: Partial) { - /* eslint-disable-next-line */ - const defaultState = configureStore().getState() as any as CombinedState<{ - unifiedAlerting: Required; - }>; +export function mockUnifiedAlertingStore(unifiedAlerting?: Partial) { + const defaultState = configureStore().getState(); return configureStore({ ...defaultState, @@ -724,19 +720,10 @@ export function mockUnifiedAlertingStore(unifiedAlerting?: Partial Promise | void) { - /* eslint-disable-next-line */ - const defaultState = configureStore().getState() as PreloadedState; - - return configureStore( - // @ts-ignore - produce(defaultState, recipe as (state: StoreState) => Promise) as Promise< - Required> - > - ); +export function mockStore(recipe: (state: StoreState) => void) { + const defaultState = configureStore().getState(); + + return configureStore(produce(defaultState, recipe)); } export function mockAlertQuery(query: Partial): AlertQuery { diff --git a/public/app/features/alerting/unified/state/actions.ts b/public/app/features/alerting/unified/state/actions.ts index 7add27e7c008d..3927496017958 100644 --- a/public/app/features/alerting/unified/state/actions.ts +++ b/public/app/features/alerting/unified/state/actions.ts @@ -20,7 +20,12 @@ import { import { PromApplication, RulerRuleDTO, RulerRulesConfigDTO } from 'app/types/unified-alerting-dto'; import { backendSrv } from '../../../../core/services/backend_srv'; -import { logInfo, LogMessages, withPerformanceLogging } from '../Analytics'; +import { + logMeasurement, + withPerformanceLogging, + withPromRulesMetadataLogging, + withRulerRulesMetadataLogging, +} from '../Analytics'; import { deleteAlertManagerConfig, fetchAlertGroups, diff --git a/public/app/features/api-keys/ApiKeysPage.test.tsx b/public/app/features/api-keys/ApiKeysPage.test.tsx index 61fda18b90136..a2ab2351547ba 100644 --- a/public/app/features/api-keys/ApiKeysPage.test.tsx +++ b/public/app/features/api-keys/ApiKeysPage.test.tsx @@ -51,7 +51,7 @@ const setup = (propOverrides: Partial) => { Object.assign(props, propOverrides); const { rerender } = render( - + ); diff --git a/public/app/features/dashboard-scene/sharing/ExportButton/ExportMenu.tsx b/public/app/features/dashboard-scene/sharing/ExportButton/ExportMenu.tsx index a9b3f91b0aad7..02e99fe5ff92a 100644 --- a/public/app/features/dashboard-scene/sharing/ExportButton/ExportMenu.tsx +++ b/public/app/features/dashboard-scene/sharing/ExportButton/ExportMenu.tsx @@ -1,22 +1,16 @@ import { useCallback } from 'react'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors'; -import { SceneObject } from '@grafana/scenes'; +import { locationService } from '@grafana/runtime'; import { IconName, Menu } from '@grafana/ui'; import { t } from 'app/core/internationalization'; import { getTrackingSource, shareDashboardType } from 'app/features/dashboard/components/ShareModal/utils'; import { DashboardScene } from '../../scene/DashboardScene'; import { DashboardInteractions } from '../../utils/interactions'; -import { ShareDrawer } from '../ShareDrawer/ShareDrawer'; -import { SceneShareDrawerState } from '../types'; - -import { ExportAsJson } from './ExportAsJson'; const newExportButtonSelector = e2eSelectors.pages.Dashboard.DashNav.NewExportButton.Menu; -type CustomDashboardDrawer = new (...args: SceneShareDrawerState[]) => SceneObject; - export interface ExportDrawerMenuItem { shareId: string; testId: string; @@ -34,17 +28,9 @@ export function addDashboardExportDrawerItem(item: ExportDrawerMenuItem) { } export default function ExportMenu({ dashboard }: { dashboard: DashboardScene }) { - const onMenuItemClick = useCallback( - (title: string, component: CustomDashboardDrawer) => { - const drawer = new ShareDrawer({ - title, - body: new component(), - }); - - dashboard.showModal(drawer); - }, - [dashboard] - ); + const onMenuItemClick = (shareView: string) => { + locationService.partial({ shareView }); + }; const buildMenuItems = useCallback(() => { const menuItems: ExportDrawerMenuItem[] = []; @@ -57,11 +43,11 @@ export default function ExportMenu({ dashboard }: { dashboard: DashboardScene }) icon: 'arrow', label: t('share-dashboard.menu.export-json-title', 'Export as JSON'), renderCondition: true, - onClick: () => onMenuItemClick(t('export.json.title', 'Save dashboard JSON'), ExportAsJson), + onClick: () => onMenuItemClick(shareDashboardType.export), }); return menuItems.filter((item) => item.renderCondition); - }, [onMenuItemClick]); + }, []); const onClick = (item: ExportDrawerMenuItem) => { DashboardInteractions.sharingCategoryClicked({ diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index 6346aef2642e0..dbd4c0a14e485 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -1,4 +1,5 @@ import { css } from '@emotion/css'; +import { noop } from 'lodash'; import { memo, ReactNode } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { useLocation } from 'react-router-dom-v5-compat'; @@ -14,6 +15,7 @@ import { ToolbarButtonRow, ConfirmModal, Badge, + PageToolbar, } from '@grafana/ui'; import { updateNavIndex } from 'app/core/actions'; import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate'; @@ -53,7 +55,7 @@ const mapDispatchToProps = { }; const mapStateToProps = (state: StoreState) => { - return { ...state.fnGlobalState, ...state.navIndex }; + return { ...state.fnGlobalState, navIndex: state.navIndex }; }; const connector = connect(mapStateToProps, mapDispatchToProps); @@ -275,36 +277,36 @@ export const DashNav = memo((props) => { }; const renderRightActions = () => { - const { dashboard, onAddPanel, isFullscreen, kioskMode, FNDashboard, hideTimePicker } = props; + const { dashboard, isFullscreen, kioskMode, FNDashboard, hideTimePicker } = props; const { canSave, canEdit, showSettings, canShare } = dashboard.meta; const { snapshot } = dashboard; const snapshotUrl = snapshot && snapshot.originalUrl; const buttons: ReactNode[] = []; - const tvButton = config.featureToggles.topnav ? null : ( - - ); + // const tvButton = config.featureToggles.topnav ? null : ( + // + // ); if (isPlaylistRunning()) { return [renderPlaylistControls(), renderTimeControls()]; } if (kioskMode === KioskMode.TV || kioskMode === KioskMode.FN) { - return [renderTimeControls(), tvButton]; + return [renderTimeControls()]; } if (snapshotUrl) { buttons.push( ); @@ -330,18 +332,6 @@ export const DashNav = memo((props) => { ); } - if (snapshotUrl) { - buttons.push( - gotoSnapshotOrigin(snapshotUrl)} - icon="link" - key="button-snapshot" - isHidden={!!FNDashboard} - /> - ); - } - if (showSettings) { buttons.push( ((props) => { return buttons; }; - const gotoSnapshotOrigin = (snapshotUrl: string) => { - window.location.href = textUtil.sanitizeUrl(snapshotUrl); - }; - const { isFullscreen, title, folderTitle } = props; // let titleHref = ''; @@ -395,7 +381,7 @@ export const DashNav = memo((props) => { // parentHref = locationUtil.getUrlForPartial(location, { search: 'open', folder: 'current' }); // } - const onGoBack = isFullscreen ? onClose : undefined; + const onGoBack = isFullscreen ? onclose : undefined; if (config.featureToggles.topnav) { return ( @@ -418,7 +404,7 @@ export const DashNav = memo((props) => { parent={folderTitle} // titleHref={titleHref} // parentHref={parentHref} - onGoBack={onGoBack} + onGoBack={onGoBack ?? noop} leftItems={renderLeftActions()} > {renderRightActions()} diff --git a/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx b/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx index 142aaa4b95dd4..635d10f26a694 100644 --- a/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx +++ b/public/app/features/dashboard/components/DashboardLoading/FnLoader.tsx @@ -1,5 +1,5 @@ import { Box, CircularProgress, CircularProgressProps, Typography, type BoxProps } from '@mui/material'; -import React, { type ReactNode, type FC } from 'react'; +import { type ReactNode, type FC } from 'react'; import { useTheme2 } from '@grafana/ui'; diff --git a/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx b/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx deleted file mode 100644 index a36703ab6420f..0000000000000 --- a/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { screen, render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; - -import { createTheme } from '@grafana/data'; -import { selectors } from '@grafana/e2e-selectors'; -import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/types'; - -import { PanelModel } from '../../state/PanelModel'; - -import { DashboardRow, UnthemedDashboardRow } from './DashboardRow'; - -describe('DashboardRow', () => { - let panel: PanelModel, dashboardMock: any; - - beforeEach(() => { - dashboardMock = { - toggleRow: jest.fn(), - on: jest.fn(), - meta: { - canEdit: true, - }, - events: { subscribe: jest.fn() }, - getRowPanels: () => [], - }; - - panel = new PanelModel({ collapsed: false }); - }); - - it('Should correctly show expanded state when the panel is expanded', () => { - render(); - const row = screen.getByTestId(selectors.components.DashboardRow.title('')); - expect(row).toBeInTheDocument(); - expect(row).toHaveAttribute('aria-expanded', 'true'); - }); - - it('Should correctly show expanded state when the panel is collapsed', async () => { - const panel = new PanelModel({ collapsed: true }); - render(); - const row = screen.getByTestId(selectors.components.DashboardRow.title('')); - expect(row).toHaveAttribute('aria-expanded', 'false'); - }); - - it('Should collapse after clicking title', async () => { - render(); - await userEvent.click(screen.getByTestId('data-testid dashboard-row-title-')); - expect(dashboardMock.toggleRow.mock.calls).toHaveLength(1); - }); - - it('Should subscribe to event during mount', () => { - render(); - expect(dashboardMock.events.subscribe.mock.calls).toHaveLength(1); - }); - - it('should have a row options and delete row button', () => { - render(); - expect(screen.getByRole('button', { name: 'Delete row' })).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'Row options' })).toBeInTheDocument(); - }); - - it('should not show row drag handle when cannot edit', () => { - dashboardMock.meta.canEdit = false; - render(); - expect(screen.queryByTestId('dashboard-row-container')).toBeInTheDocument(); - expect(screen.queryByTestId('dashboard-row-drag')).not.toBeInTheDocument(); - }); - - it('should have zero actions when cannot edit', () => { - dashboardMock.meta.canEdit = false; - panel = new PanelModel({ collapsed: false }); - render(); - expect(screen.queryByRole('button', { name: 'Delete row' })).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Row options' })).not.toBeInTheDocument(); - }); - - it('Should return warning message when row panel has a panel with dashboard ds set', async () => { - const panel = new PanelModel({ - datasource: { - type: 'datasource', - uid: SHARED_DASHBOARD_QUERY, - }, - }); - const rowPanel = new PanelModel({ collapsed: true, panels: [panel] }); - const dashboardRow = new UnthemedDashboardRow({ panel: rowPanel, dashboard: dashboardMock, theme: createTheme() }); - expect(dashboardRow.getWarning()).toBeDefined(); - }); - - it('Should not return warning message when row panel does not have a panel with dashboard ds set', async () => { - const panel = new PanelModel({ - datasource: { - type: 'datasource', - uid: 'ds-uid', - }, - }); - const rowPanel = new PanelModel({ collapsed: true, panels: [panel] }); - const dashboardRow = new UnthemedDashboardRow({ panel: rowPanel, dashboard: dashboardMock, theme: createTheme() }); - expect(dashboardRow.getWarning()).not.toBeDefined(); - }); -}); diff --git a/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx b/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx index a02bd4d7f640b..9b2d69584e2f4 100644 --- a/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx +++ b/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx @@ -1,8 +1,8 @@ import { css, cx } from '@emotion/css'; import { indexOf } from 'lodash'; -import React, { Component } from 'react'; +import React from 'react'; +import { connect } from 'react-redux'; import { Unsubscribable } from 'rxjs'; -import {connect} from "react-redux" import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; @@ -10,20 +10,20 @@ import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; import { Icon, TextLink, Themeable2, withTheme2 } from '@grafana/ui'; import appEvents from 'app/core/app_events'; import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/types'; +import { StoreState } from 'app/types'; import { ShowConfirmModalEvent } from '../../../../types/events'; import { DashboardModel } from '../../state/DashboardModel'; import { PanelModel } from '../../state/PanelModel'; import { RowOptionsButton } from '../RowOptions/RowOptionsButton'; -import { StoreState } from 'app/types'; export interface DashboardRowProps extends Themeable2 { panel: PanelModel; dashboard: DashboardModel; - isFnDashboard: boolean + isFnDashboard: boolean; } - class Component extends React.Component { +class Component extends React.Component { sub?: Unsubscribable; componentDidMount() { @@ -97,18 +97,14 @@ export interface DashboardRowProps extends Themeable2 { }; render() { - const classes = classNames({ - 'dashboard-row': true, - 'dashboard-row--collapsed': this.props.panel.collapsed, - }); - - const {isFnDashboard} = this.props + const { isFnDashboard } = this.props; const title = getTemplateSrv().replace(this.props.panel.title, this.props.panel.scopedVars, 'text'); const count = this.props.panel.panels ? this.props.panel.panels.length : 0; const panels = count === 1 ? 'panel' : 'panels'; const canEdit = this.props.dashboard.meta.canEdit === true && !isFnDashboard; - + const styles = getStyles(this.props.theme); + const collapsed = this.props.panel.collapsed; return (
({ - isFnDashboard: state.fnGlobalState.FNDashboard +function mapStateToProps() { + return (state: StoreState) => ({ + isFnDashboard: state.fnGlobalState.FNDashboard, }); } +export const DashboardRow = withTheme2(connect(mapStateToProps)(Component)); + +const getStyles = (theme: GrafanaTheme2) => { + const actions = css({ + color: theme.colors.text.secondary, + opacity: 0, + [theme.transitions.handleMotion('no-preference', 'reduce')]: { + transition: '200ms opacity ease-in 200ms', + }, + + button: { + color: theme.colors.text.secondary, + paddingLeft: theme.spacing(2), + background: 'transparent', + border: 'none', -export const DashboardRow = connect(mapStateToProps)(Component); + '&:hover': { + color: theme.colors.text.maxContrast, + }, + }, + }); + + return { + dashboardRow: css({ + display: 'flex', + alignItems: 'center', + height: '100%', + + '&:hover, &:focus-within': { + [`.${actions}`]: { + opacity: 1, + }, + }, + }), + dashboardRowCollapsed: css({ + background: theme.components.panel.background, + }), + toggleTargetCollapsed: css({ + flex: 1, + cursor: 'pointer', + marginRight: '15px', + }), + title: css({ + flexGrow: 0, + fontSize: theme.typography.h5.fontSize, + fontWeight: theme.typography.fontWeightMedium, + color: theme.colors.text.primary, + background: 'transparent', + border: 'none', + + '.fa': { + color: theme.colors.text.secondary, + fontSize: theme.typography.size.xs, + padding: theme.spacing(0, 1), + }, + }), + actions, + count: css({ + paddingLeft: theme.spacing(2), + color: theme.colors.text.secondary, + fontStyle: 'italic', + fontSize: theme.typography.size.sm, + fontWeight: 'normal', + display: 'none', + }), + countCollapsed: css({ + display: 'inline-block', + }), + dragHandle: css({ + cursor: 'move', + width: '16px', + height: '100%', + background: 'url("public/img/grab_dark.svg") no-repeat 50% 50%', + backgroundSize: '8px', + visibility: 'hidden', + position: 'absolute', + top: 0, + right: 0, + }), + dragHandleCollapsed: css({ + visibility: 'visible', + opacity: 1, + }), + }; +}; diff --git a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx index 1376480db8c94..8b6045b57ff21 100644 --- a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx @@ -21,7 +21,7 @@ function setup(dashboard: DashboardModel, editIndex?: number) { }; return render( - + ); diff --git a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx index 0ce6336bc2275..21e7144ba45c1 100644 --- a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx @@ -2,14 +2,12 @@ import { screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { render } from 'test/test-utils'; -import { configureStore } from '../../../../store/configureStore'; import { DashboardModel } from '../../state'; import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures'; import { DashboardSettings } from './DashboardSettings'; function setup(dashboard: DashboardModel) { - const store = configureStore(); const sectionNav = { main: { text: 'Dashboard' }, node: { diff --git a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx index 9f209f471ddd3..aa2b80a47b974 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx @@ -1,19 +1,18 @@ import { css } from '@emotion/css'; -import React, { PureComponent } from 'react'; +import { PureComponent } from 'react'; import { connect, MapStateToProps } from 'react-redux'; -import { AnnotationQuery, DataQuery, GrafanaTheme2 } from '@grafana/data'; +import { AnnotationQuery, DataQuery, GrafanaTheme2, TypedVariableModel } from '@grafana/data'; +import { DashboardLink } from '@grafana/schema/dist/esm/index'; import { stylesFactory, Themeable2, withTheme2 } from '@grafana/ui'; import { StoreState } from '../../../../types'; import { getSubMenuVariables, getVariablesState } from '../../../variables/state/selectors'; -import { VariableModel } from '../../../variables/types'; import { DashboardModel } from '../../state'; import { Annotations } from './Annotations'; import { DashboardLinks } from './DashboardLinks'; import { SubMenuItems } from './SubMenuItems'; -import { DashboardLink } from '@grafana/schema/dist/esm/index'; interface OwnProps extends Themeable2 { dashboard: DashboardModel; @@ -22,7 +21,7 @@ interface OwnProps extends Themeable2 { } interface ConnectedProps { - variables: VariableModel[]; + variables: TypedVariableModel[]; } interface DispatchProps {} diff --git a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx index 9200b4cf45326..4c9a0afffd57b 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx @@ -4,16 +4,15 @@ import { useEffect, useState } from 'react'; import { GrafanaTheme2, TypedVariableModel, VariableHide } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { useStyles2 } from '@grafana/ui'; +import { useSelector } from 'app/types'; import { PickerRenderer } from '../../../variables/pickers/PickerRenderer'; -import { useSelector } from 'app/types'; interface Props { variables: TypedVariableModel[]; readOnly?: boolean; } - export const SubMenuItems = ({ variables, readOnly }: Props) => { const [visibleVariables, setVisibleVariables] = useState([]); diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index 3bb683e8cae91..5ebe4cbcd006c 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -179,7 +179,7 @@ export class UnthemedDashboardPage extends PureComponent { urlSlug: match.params.slug, urlUid: match.params.uid, urlType: match.params.type, - urlFolderUid: queryParams.folderUid, + // urlFolderUid: queryParams.folderUid, panelType: queryParams.panelType, routeName: this.props.route.routeName, fixUrl: !FNDashboard, @@ -379,7 +379,7 @@ export class UnthemedDashboardPage extends PureComponent { render() { const { dashboard, initError, queryParams, FNDashboard, controlsContainer } = this.props; - const { editPanel, viewPanel, updateScrollTop, pageNav, sectionNav } = this.state; + const { editPanel, viewPanel, pageNav, sectionNav } = this.state; const kioskMode = getKioskMode(this.props.queryParams); if (!dashboard) { @@ -423,8 +423,8 @@ export class UnthemedDashboardPage extends PureComponent { pageNav={pageNav} layout={PageLayoutType.Canvas} className={pageClassName} - scrollRef={this.setScrollRef} - scrollTop={updateScrollTop} + // scrollRef={this.setScrollRef} + // scrollTop={updateScrollTop} style={{ minHeight: '550px' }} > {showToolbar && ( @@ -437,7 +437,7 @@ export class UnthemedDashboardPage extends PureComponent { title={dashboard.title} folderTitle={dashboard.meta.folderTitle} isFullscreen={!!viewPanel} - onAddPanel={this.onAddPanel} + // onAddPanel={this.onAddPanel} kioskMode={kioskMode} hideTimePicker={dashboard.timepicker.hidden} /> diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx index be9499a53de65..fef25cc59b942 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx @@ -17,7 +17,7 @@ import { DashboardMeta } from 'app/types'; import { DashboardModel } from '../state'; import { createDashboardModelFixture } from '../state/__fixtures__/dashboardFixtures'; -import { DashboardGrid, PANEL_FILTER_VARIABLE, Props } from './DashboardGrid'; +import { DashboardGrid, Props } from './DashboardGrid'; import { Props as LazyLoaderProps } from './LazyLoader'; jest.mock('@grafana/runtime', () => ({ @@ -133,7 +133,7 @@ describe('DashboardGrid', () => { refreshAll: false, variable: { type: 'textbox', - id: PANEL_FILTER_VARIABLE, + id: '1', current: { value: 'My graph', }, @@ -158,7 +158,7 @@ describe('DashboardGrid', () => { isEditable: true, dashboard: getTestDashboard(undefined, undefined, () => [ { - id: PANEL_FILTER_VARIABLE, + id: '1', type: 'textbox', query: 'My tab', } as TextBoxVariableModel, diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index 252381314fee4..70c88a5d54182 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -12,7 +12,6 @@ import { StoreState } from 'app/types'; import { DashboardPanelsChangedEvent } from 'app/types/events'; import { AddLibraryPanelWidget } from '../components/AddLibraryPanelWidget'; -import { AddPanelWidget } from '../components/AddPanelWidget'; import { DashboardRow } from '../components/DashboardRow'; import { DashboardModel, PanelModel } from '../state'; import { GridPos } from '../state/PanelModel'; @@ -182,11 +181,6 @@ export class Component extends PureComponent { return ; } - // Todo: Remove this when we remove the emptyDashboardPage toggle - if (panel.type === 'add-panel') { - return ; - } - if (panel.type === 'add-library-panel') { return ; } diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index 51f6410d6e6b7..b2c34f0b392b8 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -34,7 +34,6 @@ const mapStateToProps = (state: StoreState, props: OwnProps) => { return { plugin: panelState.plugin, instanceState: panelState.instanceState, - fnGlobalState: state.fnGlobalState, }; }; @@ -46,6 +45,7 @@ const mapDispatchToProps = { const connector = connect(mapStateToProps, mapDispatchToProps); export type Props = OwnProps & ConnectedProps; + export class DashboardPanelUnconnected extends PureComponent { static defaultProps: Partial = { lazy: true, @@ -58,7 +58,7 @@ export class DashboardPanelUnconnected extends PureComponent { } } - onInstanceStateChange = (value: unknown) => { + onInstanceStateChange = (value: any) => { this.props.setPanelInstanceState({ key: this.props.stateKey, value }); }; @@ -72,7 +72,7 @@ export class DashboardPanelUnconnected extends PureComponent { } }; - renderPanel = (isInView: boolean) => { + renderPanel = ({ isInView }: { isInView: boolean }) => { const { dashboard, panel, @@ -82,12 +82,10 @@ export class DashboardPanelUnconnected extends PureComponent { height, plugin, timezone, - fnGlobalState, + hideMenu, isDraggable = true, } = this.props; - // console.log(this.props, "on render panel") - if (!plugin) { return null; } @@ -121,8 +119,7 @@ export class DashboardPanelUnconnected extends PureComponent { height={height} onInstanceStateChange={this.onInstanceStateChange} timezone={timezone} - mode={fnGlobalState.mode} - FNDashboard={fnGlobalState.FNDashboard} + hideMenu={hideMenu} /> ); }; @@ -135,7 +132,7 @@ export class DashboardPanelUnconnected extends PureComponent { {this.renderPanel} ) : ( - this.renderPanel(true) + this.renderPanel({ isInView: true }) ); } } diff --git a/public/app/features/dashboard/dashgrid/LazyLoader.tsx b/public/app/features/dashboard/dashgrid/LazyLoader.tsx index e42d4c8f9c994..1472acda3d657 100644 --- a/public/app/features/dashboard/dashgrid/LazyLoader.tsx +++ b/public/app/features/dashboard/dashgrid/LazyLoader.tsx @@ -1,4 +1,4 @@ -import React, { useId, useRef, useState } from 'react'; +import { useId, useRef, useState } from 'react'; import { useEffectOnce } from 'react-use'; export interface Props { diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx index 9431e752c4306..2a727be141fe3 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx @@ -1,124 +1,121 @@ -import { css, cx } from '@emotion/css'; -import React, { FC } from 'react'; +// import { css, cx } from '@emotion/css'; +// import { FC } from 'react'; -import { DataLink, GrafanaTheme2, PanelData } from '@grafana/data'; -import { selectors } from '@grafana/e2e-selectors'; -import { Icon, useStyles2, ClickOutsideWrapper } from '@grafana/ui'; -import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; -import { PanelModel } from 'app/features/dashboard/state/PanelModel'; -import { getPanelLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers'; -import { StoreState, useSelector } from 'app/types'; +// import { DataLink, GrafanaTheme2, PanelData } from '@grafana/data'; +// import { selectors } from '@grafana/e2e-selectors'; +// import { Icon, useStyles2, ClickOutsideWrapper } from '@grafana/ui'; +// import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; +// import { PanelModel } from 'app/features/dashboard/state/PanelModel'; +// import { getPanelLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers'; +// import { StoreState, useSelector } from 'app/types'; -import PanelHeaderCorner from './PanelHeaderCorner'; -import { PanelHeaderLoadingIndicator } from './PanelHeaderLoadingIndicator'; -import { PanelHeaderMenuTrigger } from './PanelHeaderMenuTrigger'; -import { PanelHeaderMenuWrapper } from './PanelHeaderMenuWrapper'; -import { PanelHeaderNotices } from './PanelHeaderNotices'; +// import { PanelHeaderMenuWrapper } from './PanelHeaderMenuWrapper'; +// import { PanelHeaderNotices } from './PanelHeaderNotices'; +// import PanelHeaderCorner from '../../components/PanelEditor/PanelHeaderCorner'; -export interface Props { - panel: PanelModel; - dashboard: DashboardModel; - title?: string; - description?: string; - links?: DataLink[]; - error?: string; - alertState?: string; - isViewing: boolean; - isEditing: boolean; - data: PanelData; -} +// export interface Props { +// panel: PanelModel; +// dashboard: DashboardModel; +// title?: string; +// description?: string; +// links?: DataLink[]; +// error?: string; +// alertState?: string; +// isViewing: boolean; +// isEditing: boolean; +// data: PanelData; +// } -export const PanelHeader: FC = ({ panel, error, isViewing, isEditing, data, alertState, dashboard }) => { +// export const PanelHeader: FC = ({ panel, error, isViewing, isEditing, data, alertState, dashboard }) => { +// const isFnDashboard = useSelector((state: StoreState) => { +// const { +// fnGlobalState: { FNDashboard }, +// } = state; - const isFnDashboard = useSelector((state: StoreState) => { - const { - fnGlobalState: { FNDashboard }, - } = state; +// return FNDashboard; +// }); - return FNDashboard; - }); +// const onCancelQuery = () => panel.getQueryRunner().cancelQuery(); +// const title = panel.getDisplayTitle(); +// const className = cx('panel-header', !(isViewing || isEditing) ? 'grid-drag-handle' : ''); +// const styles = useStyles2(panelStyles); - const onCancelQuery = () => panel.getQueryRunner().cancelQuery(); - const title = panel.getDisplayTitle(); - const className = cx('panel-header', !(isViewing || isEditing) ? 'grid-drag-handle' : ''); - const styles = useStyles2(panelStyles); +// return ( +// <> +// +// +//
+// +// {({ closeMenu, panelMenuOpen }) => { +// return ( +// +//
+// +// {alertState ? ( +// +// ) : null} +//

{title}

+// {isFnDashboard +// ? null +// : !dashboard.meta.publicDashboardAccessToken && ( +//
+// +// {panelMenuOpen ? ( +// +// ) : null} +//
+// )} +// {data.request && data.request.timeInfo && ( +// +// {data.request.timeInfo} +// +// )} +//
+//
+// ); +// }} +//
+//
+// +// ); +// }; - return ( - <> - - -
- - {({ closeMenu, panelMenuOpen }) => { - return ( - -
- - {alertState ? ( - - ) : null} -

{title}

- {isFnDashboard - ? null - : !dashboard.meta.publicDashboardAccessToken && ( -
- - {panelMenuOpen ? ( - - ) : null} -
- )} - {data.request && data.request.timeInfo && ( - - {data.request.timeInfo} - - )} -
-
- ); - }} -
-
- - ); -}; +// const panelStyles = (theme: GrafanaTheme2) => { +// return { +// fnPanelHeader: css` +// &:hover { +// background-color: initial !important; +// cursor: default !important; +// } +// `, +// titleText: css` +// text-overflow: ellipsis; +// overflow: hidden; +// white-space: nowrap; +// max-width: calc(100% - 38px); +// cursor: pointer; +// font-weight: ${theme.typography.fontWeightMedium}; +// font-size: ${theme.typography.body.fontSize}; +// margin: 0; -const panelStyles = (theme: GrafanaTheme2) => { - return { - fnPanelHeader: css` - &:hover { - background-color: initial!important; - cursor: default!important; - } - `, - titleText: css` - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - max-width: calc(100% - 38px); - cursor: pointer; - font-weight: ${theme.typography.fontWeightMedium}; - font-size: ${theme.typography.body.fontSize}; - margin: 0; - - &:hover { - color: ${theme.colors.text.primary}; - } - .panel-has-alert & { - max-width: calc(100% - 54px); - } - `, - }; -}; +// &:hover { +// color: ${theme.colors.text.primary}; +// } +// .panel-has-alert & { +// max-width: calc(100% - 54px); +// } +// `, +// }; +// }; diff --git a/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx b/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx index 34a122e424f91..7d21b626fa3cd 100644 --- a/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx +++ b/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx @@ -1,5 +1,5 @@ -import classNames from 'classnames'; -import React, { PureComponent, CSSProperties } from 'react'; +import { debounce } from 'lodash'; +import { PureComponent } from 'react'; import { Subscription } from 'rxjs'; import { @@ -26,7 +26,7 @@ import { RefreshEvent } from '@grafana/runtime'; import { VizLegendOptions } from '@grafana/schema'; import { ErrorBoundary, - PanelChrome as Panel, + PanelChrome, PanelContext, PanelContextProvider, SeriesVisibilityChangeMode, @@ -40,6 +40,7 @@ import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { applyFilterFromTable } from 'app/features/variables/adhoc/actions'; import { onUpdatePanelSnapshotData } from 'app/plugins/datasource/grafana/utils'; import { changeSeriesColorConfigFactory } from 'app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory'; +import { dispatch } from 'app/store/store'; import { RenderEvent } from 'app/types/events'; import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../annotations/api'; @@ -70,8 +71,6 @@ export interface Props { onInstanceStateChange: (value: unknown) => void; timezone?: string; hideMenu?: boolean; - FNDashboard?: boolean; - mode?: "light" | "dark"; } export interface State { @@ -83,12 +82,6 @@ export interface State { liveTime?: TimeRange; } -const FN_TITLE_STYLE: CSSProperties = { - textAlign: 'center', - padding: 3, - textTransform: 'capitalize', -}; - export class PanelStateWrapper extends PureComponent { private readonly timeSrv: TimeSrv = getTimeSrv(); private subs = new Subscription(); @@ -295,7 +288,6 @@ export class PanelStateWrapper extends PureComponent { if (width !== prevProps.width) { liveTimer.updateInterval(this); } - } // Updates the response with information from the stream @@ -563,7 +555,7 @@ export class PanelStateWrapper extends PureComponent { debouncedSetPanelAttention() {} render() { - const { dashboard, panel, isViewing, isEditing, width, height, plugin, FNDashboard } = this.props; + const { dashboard, panel, width, height, plugin } = this.props; const { errorMessage, data } = this.state; const { transparent } = panel; const panelChromeProps = getPanelChromeProps({ ...this.props, data }); @@ -577,69 +569,45 @@ export class PanelStateWrapper extends PureComponent {
); - // for new panel header design - const onCancelQuery = () => panel.getQueryRunner().cancelQuery(); - const title = panel.getDisplayTitle(); - const noPadding: PanelPadding = plugin.noPadding ? 'none' : 'md'; - const leftItems = [ - , - ]; - - if (config.featureToggles.newPanelChromeUI) { - return ( - - {(innerWidth, innerHeight) => ( - <> - - {({ error }) => { - if (error) { - return null; - } - return this.renderPanelContent(innerWidth, innerHeight); - }} - - - )} - - ); - } else { - return ( -
-
- -
- - {({ error }) => { - if (error) { - return null; - } - return this.renderPanel(width, height); - }} - -
- ); - } + return ( + this.setPanelAttention()} + onMouseEnter={() => this.setPanelAttention()} + onMouseMove={() => this.debouncedSetPanelAttention()} + > + {(innerWidth, innerHeight) => ( + <> + + {({ error }) => { + if (error) { + return null; + } + return this.renderPanelContent(innerWidth, innerHeight); + }} + + + )} + + ); } } diff --git a/public/app/features/dashboard/dashgrid/liveTimer.ts b/public/app/features/dashboard/dashgrid/liveTimer.ts index 3df0b04202292..874bceb245274 100644 --- a/public/app/features/dashboard/dashgrid/liveTimer.ts +++ b/public/app/features/dashboard/dashgrid/liveTimer.ts @@ -3,8 +3,6 @@ import { BehaviorSubject } from 'rxjs'; import { dateMath, dateTime, TimeRange } from '@grafana/data'; import { PanelStateWrapper } from './PanelStateWrapper'; -import { Props } from './PanelChrome'; - // target is 20hz (50ms), but we poll at 100ms to smooth out jitter const interval = 100; diff --git a/public/app/features/dashboard/services/DashboardLoaderSrv.ts b/public/app/features/dashboard/services/DashboardLoaderSrv.ts index 55783a4716d2f..797ccdc3d0d17 100644 --- a/public/app/features/dashboard/services/DashboardLoaderSrv.ts +++ b/public/app/features/dashboard/services/DashboardLoaderSrv.ts @@ -7,12 +7,10 @@ import { getBackendSrv, locationService } from '@grafana/runtime'; import { backendSrv } from 'app/core/services/backend_srv'; import impressionSrv from 'app/core/services/impression_srv'; import kbn from 'app/core/utils/kbn'; -import { getDashboardScenePageStateManager } from 'app/features/dashboard-scene/pages/DashboardScenePageStateManager'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { DashboardDTO } from 'app/types'; import { appEvents } from '../../../core/core'; -import { getDashboardAPI } from '../api/dashboard_api'; import { getDashboardSrv } from './DashboardSrv'; import { getDashboardSnapshotSrv } from './SnapshotSrv'; @@ -35,7 +33,7 @@ export class DashboardLoaderSrv { }; } - loadDashboard(type: UrlQueryValue, slug: any, uid: any, version: any) { + loadDashboard(type: UrlQueryValue, slug: any, uid: any, version?: any) { let promise; if (type === 'script' && slug) { @@ -77,17 +75,17 @@ export class DashboardLoaderSrv { }); } else if (version !== undefined) { promise = backendSrv - .getDashboardByUidVersion(uid, version) - .then((result: any) => { - if (result.meta.isFolder) { - appEvents.emit(AppEvents.alertError, ['Dashboard with version not found']); - throw new Error('Dashboard with version not found'); - } - return result; - }) - .catch(() => { - return this._dashboardLoadFailed('Not found', true); - }); + .getDashboardByUidVersion(uid, version) + .then((result: any) => { + if (result.meta.isFolder) { + appEvents.emit(AppEvents.alertError, ['Dashboard with version not found']); + throw new Error('Dashboard with version not found'); + } + return result; + }) + .catch(() => { + return this._dashboardLoadFailed('Not found', true); + }); } else { promise = backendSrv .getDashboardByUid(uid) @@ -103,8 +101,6 @@ export class DashboardLoaderSrv { dash.dashboard.uid = uid; return dash; }); - } else { - throw new Error('Dashboard uid or slug required'); } promise.then((result: DashboardDTO) => { diff --git a/public/app/features/dashboard/state/initDashboard.test.ts b/public/app/features/dashboard/state/initDashboard.test.ts index d291b62f37921..c4e149ada684a 100644 --- a/public/app/features/dashboard/state/initDashboard.test.ts +++ b/public/app/features/dashboard/state/initDashboard.test.ts @@ -274,7 +274,7 @@ describeInitScenario('Initializing new dashboard', (ctx) => { expect(getTimeSrv().init).toBeCalled(); expect(getDashboardSrv().setCurrent).toBeCalled(); expect(getDashboardQueryRunner().run).toBeCalled(); - expect(ctx.args.keybindingSrv.setupDashboardBindings).toBeCalled(); + expect(ctx.args.keybindingSrv?.setupDashboardBindings).toBeCalled(); }); }); @@ -409,7 +409,7 @@ describeInitScenario('Initializing existing dashboard', (ctx) => { expect(getTimeSrv().init).toBeCalled(); expect(getDashboardSrv().setCurrent).toBeCalled(); expect(getDashboardQueryRunner().run).toBeCalled(); - expect(ctx.args.keybindingSrv.setupDashboardBindings).toBeCalled(); + expect(ctx.args.keybindingSrv?.setupDashboardBindings).toBeCalled(); }); it('Should initialize redux variables if newVariables is enabled', () => { diff --git a/public/app/features/dashboard/state/initDashboard.ts b/public/app/features/dashboard/state/initDashboard.ts index 59eb5203abf12..ce057cb365f40 100644 --- a/public/app/features/dashboard/state/initDashboard.ts +++ b/public/app/features/dashboard/state/initDashboard.ts @@ -88,7 +88,12 @@ async function fetchDashboard( return await dashboardLoaderSrv.loadDashboard('public', args.urlSlug, args.accessToken, args.version); } case DashboardRoutes.Normal: { - const dashDTO: DashboardDTO = await dashboardLoaderSrv.loadDashboard(args.urlType, args.urlSlug, args.urlUid, args.version); + const dashDTO: DashboardDTO = await dashboardLoaderSrv.loadDashboard( + args.urlType, + args.urlSlug, + args.urlUid, + args.version + ); // only the folder API has information about ancestors // get parent folder (if it exists) and put it in the store @@ -121,10 +126,10 @@ async function fetchDashboard( // only the folder API has information about ancestors // get parent folder (if it exists) and put it in the store // this will be used to populate the full breadcrumb trail - if (args.urlFolderUid) { - await dispatch(getFolderByUid(args.urlFolderUid)); + if (args.urlFolderId) { + await dispatch(getFolderByUid(args.urlFolderId)); } - return await buildNewDashboardSaveModel(args.urlFolderUid); + return await buildNewDashboardSaveModel(args.urlFolderId); } case DashboardRoutes.Path: { const path = args.urlSlug ?? ''; diff --git a/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx b/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx index efed2c92f06cc..b55ccdbdf7604 100644 --- a/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx +++ b/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx @@ -15,7 +15,7 @@ import { css } from '@emotion/css'; import { SpanStatusCode } from '@opentelemetry/api'; import { uniq } from 'lodash'; -import React, { useState, useEffect, memo, useCallback } from 'react'; +import { useState, useEffect, memo, useCallback } from 'react'; import { GrafanaTheme2, SelectableValue, toOption } from '@grafana/data'; import { AccessoryButton } from '@grafana/experimental'; diff --git a/public/app/features/org/OrgDetailsPage.test.tsx b/public/app/features/org/OrgDetailsPage.test.tsx index 75c5c14720c63..0fc7ab9e728fd 100644 --- a/public/app/features/org/OrgDetailsPage.test.tsx +++ b/public/app/features/org/OrgDetailsPage.test.tsx @@ -4,7 +4,6 @@ import { mockToolkitActionCreator } from 'test/core/redux/mocks'; import { TestProvider } from 'test/helpers/TestProvider'; import { NavModel } from '@grafana/data'; -import { ModalManager } from 'app/core/services/ModalManager'; import { backendSrv } from '../../core/services/backend_srv'; import { Organization } from '../../types'; diff --git a/public/app/features/plugins/built_in_plugins.ts b/public/app/features/plugins/built_in_plugins.ts index aa89a15f10c3f..940c1310678d2 100644 --- a/public/app/features/plugins/built_in_plugins.ts +++ b/public/app/features/plugins/built_in_plugins.ts @@ -15,49 +15,55 @@ const influxdbPlugin = async () => const lokiPlugin = async () => await import(/* webpackChunkName: "lokiPlugin" */ 'app/plugins/datasource/loki/module'); const mixedPlugin = async () => await import(/* webpackChunkName: "mixedPlugin" */ 'app/plugins/datasource/mixed/module'); -const mysqlPlugin = async () => - await import(/* webpackChunkName: "mysqlPlugin" */ 'app/plugins/datasource/mysql/module'); -const postgresPlugin = async () => - await import(/* webpackChunkName: "postgresPlugin" */ 'app/plugins/datasource/postgres/module'); -const grafadruidDruidDatasourcePlugin = async () => - await import(/* webpackChunkName: "druidPlugin" */ 'app/plugins/datasource/grafadruid-druid-datasource/module'); const prometheusPlugin = async () => await import(/* webpackChunkName: "prometheusPlugin" */ 'app/plugins/datasource/prometheus/module'); -const mssqlPlugin = async () => - await import(/* webpackChunkName: "mssqlPlugin" */ 'app/plugins/datasource/mssql/module'); const alertmanagerPlugin = async () => await import(/* webpackChunkName: "alertmanagerPlugin" */ 'app/plugins/datasource/alertmanager/module'); import { config } from '@grafana/runtime'; -import * as alertListPanel from 'app/plugins/panel/alertlist/module'; -import * as annoListPanel from 'app/plugins/panel/annolist/module'; -import * as barChartPanel from 'app/plugins/panel/barchart/module'; -import * as barGaugePanel from 'app/plugins/panel/bargauge/module'; -import * as candlestickPanel from 'app/plugins/panel/candlestick/module'; -import * as dashListPanel from 'app/plugins/panel/dashlist/module'; -import * as dataGridPanel from 'app/plugins/panel/datagrid/module'; -import * as debugPanel from 'app/plugins/panel/debug/module'; -import * as flamegraphPanel from 'app/plugins/panel/flamegraph/module'; -import * as gaugePanel from 'app/plugins/panel/gauge/module'; -import * as gettingStartedPanel from 'app/plugins/panel/gettingstarted/module'; -import * as histogramPanel from 'app/plugins/panel/histogram/module'; -import * as livePanel from 'app/plugins/panel/live/module'; -import * as logsPanel from 'app/plugins/panel/logs/module'; -import * as newsPanel from 'app/plugins/panel/news/module'; -import * as pieChartPanel from 'app/plugins/panel/piechart/module'; -//@ts-ignore -import * as sankeyPanel from 'app/plugins/panel/sankey-panel-0.5.0/module'; -import * as statPanel from 'app/plugins/panel/stat/module'; -import * as stateTimelinePanel from 'app/plugins/panel/state-timeline/module'; -import * as statusHistoryPanel from 'app/plugins/panel/status-history/module'; -import * as tablePanel from 'app/plugins/panel/table/module'; -import * as textPanel from 'app/plugins/panel/text/module'; -import * as timeseriesPanel from 'app/plugins/panel/timeseries/module'; -import * as tracesPanel from 'app/plugins/panel/traces/module'; -import * as trendPanel from 'app/plugins/panel/trend/module'; -import * as welcomeBanner from 'app/plugins/panel/welcome/module'; // Async loaded panels +const alertListPanel = async () => + await import(/* webpackChunkName: "alertListPanel" */ 'app/plugins/panel/alertlist/module'); +const annoListPanel = async () => + await import(/* webpackChunkName: "annoListPanel" */ 'app/plugins/panel/annolist/module'); +const barChartPanel = async () => + await import(/* webpackChunkName: "barChartPanel" */ 'app/plugins/panel/barchart/module'); +const barGaugePanel = async () => + await import(/* webpackChunkName: "barGaugePanel" */ 'app/plugins/panel/bargauge/module'); +const candlestickPanel = async () => + await import(/* webpackChunkName: "candlestickPanel" */ 'app/plugins/panel/candlestick/module'); +const dashListPanel = async () => + await import(/* webpackChunkName: "dashListPanel" */ 'app/plugins/panel/dashlist/module'); +const dataGridPanel = async () => + await import(/* webpackChunkName: "dataGridPanel" */ 'app/plugins/panel/datagrid/module'); +const debugPanel = async () => await import(/* webpackChunkName: "debugPanel" */ 'app/plugins/panel/debug/module'); +const flamegraphPanel = async () => + await import(/* webpackChunkName: "flamegraphPanel" */ 'app/plugins/panel/flamegraph/module'); +const gaugePanel = async () => await import(/* webpackChunkName: "gaugePanel" */ 'app/plugins/panel/gauge/module'); +const gettingStartedPanel = async () => + await import(/* webpackChunkName: "gettingStartedPanel" */ 'app/plugins/panel/gettingstarted/module'); +const histogramPanel = async () => + await import(/* webpackChunkName: "histogramPanel" */ 'app/plugins/panel/histogram/module'); +const livePanel = async () => await import(/* webpackChunkName: "livePanel" */ 'app/plugins/panel/live/module'); +const logsPanel = async () => await import(/* webpackChunkName: "logsPanel" */ 'app/plugins/panel/logs/module'); +const newsPanel = async () => await import(/* webpackChunkName: "newsPanel" */ 'app/plugins/panel/news/module'); +const pieChartPanel = async () => + await import(/* webpackChunkName: "pieChartPanel" */ 'app/plugins/panel/piechart/module'); +const statPanel = async () => await import(/* webpackChunkName: "statPanel" */ 'app/plugins/panel/stat/module'); +const stateTimelinePanel = async () => + await import(/* webpackChunkName: "stateTimelinePanel" */ 'app/plugins/panel/state-timeline/module'); +const statusHistoryPanel = async () => + await import(/* webpackChunkName: "statusHistoryPanel" */ 'app/plugins/panel/status-history/module'); +const tablePanel = async () => await import(/* webpackChunkName: "tablePanel" */ 'app/plugins/panel/table/module'); +const textPanel = async () => await import(/* webpackChunkName: "textPanel" */ 'app/plugins/panel/text/module'); +const timeseriesPanel = async () => + await import(/* webpackChunkName: "timeseriesPanel" */ 'app/plugins/panel/timeseries/module'); +const tracesPanel = async () => await import(/* webpackChunkName: "tracesPanel" */ 'app/plugins/panel/traces/module'); +const trendPanel = async () => await import(/* webpackChunkName: "trendPanel" */ 'app/plugins/panel/trend/module'); +const welcomeBanner = async () => + await import(/* webpackChunkName: "welcomeBanner" */ 'app/plugins/panel/welcome/module'); + const geomapPanel = async () => await import(/* webpackChunkName: "geomapPanel" */ 'app/plugins/panel/geomap/module'); const canvasPanel = async () => await import(/* webpackChunkName: "canvasPanel" */ 'app/plugins/panel/canvas/module'); const graphPanel = async () => await import(/* webpackChunkName: "graphPlugin" */ 'app/plugins/panel/graph/module'); @@ -76,65 +82,58 @@ const tableOldPanel = async () => const nodeGraph = async () => await import(/* webpackChunkName: "nodeGraphPanel" */ 'app/plugins/panel/nodeGraph/module'); -const builtInPlugins: any = { - 'app/plugins/datasource/graphite/module': graphitePlugin, - 'app/plugins/datasource/cloudwatch/module': cloudwatchPlugin, - 'app/plugins/datasource/dashboard/module': dashboardDSPlugin, - 'app/plugins/datasource/elasticsearch/module': elasticsearchPlugin, - 'app/plugins/datasource/opentsdb/module': opentsdbPlugin, - 'app/plugins/datasource/grafana/module': grafanaPlugin, - 'app/plugins/datasource/influxdb/module': influxdbPlugin, - 'app/plugins/datasource/loki/module': lokiPlugin, - 'app/plugins/datasource/jaeger/module': jaegerPlugin, - 'app/plugins/datasource/zipkin/module': zipkinPlugin, - 'app/plugins/datasource/mixed/module': mixedPlugin, - 'app/plugins/datasource/mysql/module': mysqlPlugin, - 'app/plugins/datasource/postgres/module': postgresPlugin, - 'app/plugins/datasource/mssql/module': mssqlPlugin, +const grafadruidDruidDatasourcePlugin = async () => + await import(/* webpackChunkName: "druidPlugin" */ 'app/plugins/datasource/grafadruid-druid-datasource/module'); + +const builtInPlugins: Record Promise)> = { + // datasources + 'core:plugin/graphite': graphitePlugin, + 'core:plugin/cloudwatch': cloudwatchPlugin, + 'core:plugin/dashboard': dashboardDSPlugin, + 'core:plugin/elasticsearch': elasticsearchPlugin, + 'core:plugin/opentsdb': opentsdbPlugin, + 'core:plugin/grafana': grafanaPlugin, + 'core:plugin/influxdb': influxdbPlugin, + 'core:plugin/loki': lokiPlugin, + 'core:plugin/mixed': mixedPlugin, + 'core:plugin/prometheus': prometheusPlugin, + 'core:plugin/alertmanager': alertmanagerPlugin, + // panels + 'core:plugin/text': textPanel, + 'core:plugin/timeseries': timeseriesPanel, + 'core:plugin/trend': trendPanel, + 'core:plugin/state-timeline': stateTimelinePanel, + 'core:plugin/status-history': statusHistoryPanel, + 'core:plugin/candlestick': candlestickPanel, + 'core:plugin/graph': graphPanel, + 'core:plugin/xychart': xychartPanel, + 'core:plugin/geomap': geomapPanel, + 'core:plugin/canvas': canvasPanel, + 'core:plugin/dashlist': dashListPanel, + 'core:plugin/alertlist': alertListPanel, + 'core:plugin/annolist': annoListPanel, + 'core:plugin/heatmap': heatmapPanel, + 'core:plugin/table': tablePanel, + 'core:plugin/table-old': tableOldPanel, + 'core:plugin/news': newsPanel, + 'core:plugin/live': livePanel, + 'core:plugin/stat': statPanel, + 'core:plugin/datagrid': dataGridPanel, + 'core:plugin/debug': debugPanel, + 'core:plugin/flamegraph': flamegraphPanel, + 'core:plugin/gettingstarted': gettingStartedPanel, + 'core:plugin/gauge': gaugePanel, + 'core:plugin/piechart': pieChartPanel, + 'core:plugin/bargauge': barGaugePanel, + 'core:plugin/barchart': barChartPanel, + 'core:plugin/logs': logsPanel, + 'core:plugin/traces': tracesPanel, + 'core:plugin/welcome': welcomeBanner, + 'core:plugin/nodeGraph': nodeGraph, + 'core:plugin/histogram': histogramPanel, + // Default FluxNinja Druid datasource 'app/plugins/datasource/grafadruid-druid-datasource/module': grafadruidDruidDatasourcePlugin, - 'app/plugins/datasource/prometheus/module': prometheusPlugin, - 'app/plugins/datasource/testdata/module': testDataDSPlugin, - 'app/plugins/datasource/cloud-monitoring/module': cloudMonitoringPlugin, - 'app/plugins/datasource/grafana-azure-monitor-datasource/module': azureMonitorPlugin, - 'app/plugins/datasource/tempo/module': tempoPlugin, - 'app/plugins/datasource/alertmanager/module': alertmanagerPlugin, - 'app/plugins/datasource/phlare/module': phlarePlugin, - 'app/plugins/datasource/parca/module': parcaPlugin, - - 'app/plugins/panel/text/module': textPanel, - 'app/plugins/panel/timeseries/module': timeseriesPanel, - 'app/plugins/panel/state-timeline/module': stateTimelinePanel, - 'app/plugins/panel/status-history/module': statusHistoryPanel, - 'app/plugins/panel/candlestick/module': candlestickPanel, - 'app/plugins/panel/graph/module': graphPanel, - 'app/plugins/panel/xychart/module': xyChartPanel, - 'app/plugins/panel/geomap/module': geomapPanel, - 'app/plugins/panel/canvas/module': canvasPanel, - 'app/plugins/panel/icon/module': iconPanel, - 'app/plugins/panel/dashlist/module': dashListPanel, - 'app/plugins/panel/alertlist/module': alertListPanel, - 'app/plugins/panel/annolist/module': annoListPanel, - 'app/plugins/panel/heatmap/module': config.featureToggles.useLegacyHeatmapPanel ? heatmapPanelOLD : heatmapPanel, - 'app/plugins/panel/table/module': tablePanel, - 'app/plugins/panel/table-old/module': tableOldPanel, - 'app/plugins/panel/news/module': newsPanel, - 'app/plugins/panel/live/module': livePanel, - 'app/plugins/panel/stat/module': statPanel, - 'app/plugins/panel/debug/module': debugPanel, - 'app/plugins/panel/flamegraph/module': flamegraphPanel, - 'app/plugins/panel/gettingstarted/module': gettingStartedPanel, - 'app/plugins/panel/gauge/module': gaugePanel, - 'app/plugins/panel/piechart/module': pieChartPanel, - 'app/plugins/panel/bargauge/module': barGaugePanel, - 'app/plugins/panel/barchart/module': barChartPanel, - 'app/plugins/panel/logs/module': logsPanel, - 'app/plugins/panel/traces/module': tracesPanel, - 'app/plugins/panel/welcome/module': welcomeBanner, - 'app/plugins/panel/nodeGraph/module': nodeGraph, - 'app/plugins/panel/histogram/module': histogramPanel, - 'app/plugins/panel/alertGroups/module': alertGroupsPanel, - 'app/plugins/panel/sankey-panel-0.5.0/module': sankeyPanel, }; export default builtInPlugins; diff --git a/public/app/features/profile/UserProfileEditPage.test.tsx b/public/app/features/profile/UserProfileEditPage.test.tsx index 2f196e55765bf..a8e27dcd80db3 100644 --- a/public/app/features/profile/UserProfileEditPage.test.tsx +++ b/public/app/features/profile/UserProfileEditPage.test.tsx @@ -8,7 +8,6 @@ import * as useQueryParams from 'app/core/hooks/useQueryParams'; import { TestProvider } from '../../../test/helpers/TestProvider'; import { backendSrv } from '../../core/services/backend_srv'; -import { configureStore } from '../../store/configureStore'; import { TeamPermissionLevel } from '../../types'; import { getMockTeam } from '../teams/__mocks__/teamMocks'; @@ -184,11 +183,9 @@ async function getTestContext(overrides: Partial - - - - + + + ); await waitFor(() => expect(props.initUserProfilePage).toHaveBeenCalledTimes(1)); diff --git a/public/app/features/variables/pickers/PickerRenderer.tsx b/public/app/features/variables/pickers/PickerRenderer.tsx index 7382253caecfa..50169aa291e50 100644 --- a/public/app/features/variables/pickers/PickerRenderer.tsx +++ b/public/app/features/variables/pickers/PickerRenderer.tsx @@ -1,15 +1,16 @@ // import { css } from '@emotion/css'; -import React, { CSSProperties, FunctionComponent, PropsWithChildren, ReactElement, useMemo } from 'react'; +import { CSSProperties, FunctionComponent, PropsWithChildren, ReactElement, useMemo } from 'react'; // eslint-disable-next-line no-restricted-imports import { useSelector } from 'react-redux'; +import { VariableHide } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { Tooltip } from '@grafana/ui'; import { FnGlobalState } from 'app/core/reducers/fn-slice'; import type { StoreState } from 'app/types'; import { variableAdapters } from '../adapters'; -import { VariableHide, VariableModel } from '../types'; +import { VariableModel } from '../types'; interface Props { variable: VariableModel; diff --git a/public/app/fn-app/create-mfe.ts b/public/app/fn-app/create-mfe.ts index f8946373f7d8d..2c469d86c8288 100644 --- a/public/app/fn-app/create-mfe.ts +++ b/public/app/fn-app/create-mfe.ts @@ -6,7 +6,7 @@ window.__grafana_public_path__ = import { isNull, merge, noop, pick } from 'lodash'; import React, { ComponentType } from 'react'; -import ReactDOM from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { createTheme, GrafanaThemeType } from '@grafana/data'; import { createColors } from '@grafana/data/src/themes/createColors'; @@ -183,7 +183,7 @@ class createMfe { createMfe.removeThemeLinks(createMfe.toggleTheme(mode)); const newCssLink = createMfe.styleSheetLink; - newCssLink.href = config.bootData.themePaths[mode]; + newCssLink.href = config.bootData.assets[mode]; document.body.appendChild(newCssLink); createMfe.logger.info('Successfully loaded theme.', { mode }); @@ -242,7 +242,7 @@ class createMfe { if (container) { createMfe.logger.info('Trying to unmount grafana...'); - ReactDOM.unmountComponentAtNode(container); + createRoot(container).unmount(); createMfe.logger.info('Successfully unmounted grafana.'); } else { @@ -293,11 +293,16 @@ class createMfe { static renderMfeComponent(props: FNDashboardProps, onSuccess = noop) { const container = createMfe.getContainer(props); + if (!container) { + createMfe.logger.error('Failed to render mfe component. Container does not exist.', { props }); - ReactDOM.render(React.createElement(createMfe.Component, props), container, () => { - createMfe.logger.info('Created mfe component.', { props, container }); - onSuccess(); - }); + return; + } + + const root = createRoot(container); + root.render(React.createElement(createMfe.Component, props)); + createMfe.logger.info('Created mfe component.', { props, container }); + onSuccess(); } } diff --git a/public/app/fn-app/fn-app-provider.tsx b/public/app/fn-app/fn-app-provider.tsx index 496a90a777821..04d749ecd15c0 100644 --- a/public/app/fn-app/fn-app-provider.tsx +++ b/public/app/fn-app/fn-app-provider.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, FC, PropsWithChildren } from 'react'; +import { useState, useEffect, FC, PropsWithChildren } from 'react'; import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; @@ -7,6 +7,7 @@ import { ErrorBoundaryAlert, GlobalStyles } from '@grafana/ui'; import { loadAndInitAngularIfEnabled } from 'app/angular/loadAndInitAngularIfEnabled'; import { ThemeProvider } from 'app/core/utils/ConfigProvider'; import { FnLoader } from 'app/features/dashboard/components/DashboardLoading/FnLoader'; +import { FnLoggerService } from 'app/fn_logger'; import { store } from 'app/store/store'; import { GrafanaContext } from '../core/context/GrafanaContext'; @@ -25,9 +26,9 @@ export const FnAppProvider: FC> = (props) loadAndInitAngularIfEnabled() .then(() => { setReady(true); + $('.preloader').remove(); }) - .catch((err) => console.error(err)); - return () => {}; + .catch(FnLoggerService.error); }, []); if (!store || !ready) { diff --git a/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx index d7979b2873afb..031c2858941f7 100644 --- a/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx @@ -1,5 +1,5 @@ import { pick } from 'lodash'; -import React, { FC, useMemo } from 'react'; +import { FC, useMemo } from 'react'; import { FnPropMappedFromState, fnPropsMappedFromState } from 'app/core/reducers/fn-slice'; import { StoreState, useSelector } from 'app/types'; diff --git a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx index a0f402e55cb35..e9dac0f5ce0cf 100644 --- a/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx +++ b/public/app/fn-app/fn-dashboard-page/render-fn-dashboard.tsx @@ -1,5 +1,5 @@ -import { merge, isFunction } from 'lodash'; -import React, { useEffect, FC, useMemo } from 'react'; +import { merge, isFunction } from 'lodash'; +import { useEffect, FC, useMemo } from 'react'; import { locationService as locationSrv, HistoryWrapper } from '@grafana/runtime'; import DashboardPage, { DashboardPageProps } from 'app/features/dashboard/containers/DashboardPage'; @@ -66,7 +66,7 @@ export const RenderFNDashboard: FC = (props) => { queryParams, hiddenVariables, controlsContainer, - isLoading + isLoading, }), [controlsContainer, hiddenVariables, isLoading, props, queryParams] ); diff --git a/public/app/fn-app/types.ts b/public/app/fn-app/types.ts index c1355e1602df5..4a1bf55f26909 100644 --- a/public/app/fn-app/types.ts +++ b/public/app/fn-app/types.ts @@ -1,4 +1,3 @@ -import { ParsedQuery } from 'query-string'; import { ReactNode } from 'react'; import { GrafanaThemeType } from '@grafana/data'; @@ -24,7 +23,7 @@ export interface FNDashboardProps { slug: string; version: number; mode: GrafanaThemeType.Dark | GrafanaThemeType.Light; - queryParams: ParsedQuery; + queryParams: Record; fnError?: ReactNode; pageTitle?: string; controlsContainer: string | null; diff --git a/public/app/fn-app/utils.tsx b/public/app/fn-app/utils.tsx index b4603a235c9cc..44110ffc2fd6e 100644 --- a/public/app/fn-app/utils.tsx +++ b/public/app/fn-app/utils.tsx @@ -1,5 +1,5 @@ import { Portal } from '@mui/material'; -import React, { FC, PropsWithChildren } from 'react'; +import { FC, PropsWithChildren } from 'react'; export interface RenderPortalProps { ID: string; diff --git a/public/app/fn_app.ts b/public/app/fn_app.ts index 79301e66c9916..beef41185a3b3 100644 --- a/public/app/fn_app.ts +++ b/public/app/fn_app.ts @@ -3,7 +3,6 @@ import 'core-js'; import 'regenerator-runtime/runtime'; import 'whatwg-fetch'; // fetch polyfill needed for PhantomJs rendering -import './polyfills/old-mediaquerylist'; // Safari < 14 does not have mql.addEventListener() import 'file-saver'; import 'jquery'; @@ -33,7 +32,8 @@ import { setPluginImportUtils, setPluginExtensionGetter, setAppEvents, - type GetPluginExtensions, + setPluginExtensionsHook, + setPluginComponentHook, } from '@grafana/runtime'; import { setPanelDataErrorView } from '@grafana/runtime/src/components/PanelDataErrorView'; import { setPanelRenderer } from '@grafana/runtime/src/components/PanelRenderer'; @@ -52,7 +52,7 @@ import { PluginPage } from './core/components/Page/PluginPage'; import { GrafanaContextType } from './core/context/GrafanaContext'; import { initializeI18n } from './core/internationalization'; import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks'; -import { ModalManager } from './core/services/ModalManager'; +import { NewFrontendAssetsChecker } from './core/services/NewFrontendAssetsChecker'; import { backendSrv } from './core/services/backend_srv'; import { contextSrv } from './core/services/context_srv'; import { Echo } from './core/services/echo/Echo'; @@ -71,9 +71,12 @@ import { getTimeSrv } from './features/dashboard/services/TimeSrv'; import { PanelDataErrorView } from './features/panel/components/PanelDataErrorView'; import { PanelRenderer } from './features/panel/components/PanelRenderer'; import { DatasourceSrv } from './features/plugins/datasource_srv'; -import { createPluginExtensionRegistry } from './features/plugins/extensions/createPluginExtensionRegistry'; import { getCoreExtensionConfigurations } from './features/plugins/extensions/getCoreExtensionConfigurations'; -import { getPluginExtensions } from './features/plugins/extensions/getPluginExtensions'; +import { createPluginExtensionsGetter } from './features/plugins/extensions/getPluginExtensions'; +import { ReactivePluginExtensionsRegistry } from './features/plugins/extensions/reactivePluginExtensionRegistry'; +import { ExposedComponentsRegistry } from './features/plugins/extensions/registry/ExposedComponentsRegistry'; +import { createUsePluginComponent } from './features/plugins/extensions/usePluginComponent'; +import { createUsePluginExtensions } from './features/plugins/extensions/usePluginExtensions'; import { importPanelPlugin, syncGetPanelPlugin } from './features/plugins/importPanelPlugin'; import { preloadPlugins } from './features/plugins/pluginPreloader'; import { QueryRunner } from './features/query/state/QueryRunner'; @@ -106,37 +109,11 @@ if (process.env.NODE_ENV === 'development') { initDevFeatures(); } -export declare type FNGrafanaStartupState = { - isLoading: boolean; - isError: boolean; - error?: unknown; - isIdeal: boolean; -}; - -export const DefaultGrafanaStartupState: FNGrafanaStartupState = { - isLoading: false, - isError: false, - isIdeal: true, -}; - -const dispatchFnEvent = (info: FNGrafanaStartupState = DefaultGrafanaStartupState, ek = 'grafana-startup') => { - window.dispatchEvent( - new CustomEvent(ek, { - detail: info, - }) - ); -}; - export class GrafanaApp { context!: GrafanaContextType; async init() { try { - dispatchFnEvent({ - isIdeal: false, - isLoading: true, - isError: false, - }); // Let iframe container know grafana has started loading parent.postMessage('GrafanaAppInit', '*'); @@ -216,29 +193,43 @@ export class GrafanaApp { setDataSourceSrv(dataSourceSrv); initWindowRuntime(); - // init modal manager - const modalManager = new ModalManager(); - modalManager.init(); - - // Preload selected app plugins - const preloadResults = await preloadPlugins(config.apps); - - // Create extension registry out of preloaded plugins and core extensions - const extensionRegistry = createPluginExtensionRegistry([ - { pluginId: 'grafana', extensionConfigs: getCoreExtensionConfigurations() }, - ...preloadResults, - ]); + // Initialize plugin extensions + const extensionsRegistry = new ReactivePluginExtensionsRegistry(); + extensionsRegistry.register({ + pluginId: 'grafana', + extensionConfigs: getCoreExtensionConfigurations(), + exposedComponentConfigs: [], + }); - // Expose the getPluginExtension function via grafana-runtime - const pluginExtensionGetter: GetPluginExtensions = (options) => - getPluginExtensions({ ...options, registry: extensionRegistry }); + const exposedComponentsRegistry = new ExposedComponentsRegistry(); - setPluginExtensionGetter(pluginExtensionGetter); + // Preload selected app plugins + if (contextSrv.user.orgRole !== '') { + // The "cloud-home-app" is registering banners once it's loaded, and this can cause a rerender in the AppChrome if it's loaded after the Grafana app init. + // TODO: remove the following exception once the issue mentioned above is fixed. + const awaitedAppPluginIds = ['cloud-home-app']; + const awaitedAppPlugins = Object.values(config.apps).filter((app) => awaitedAppPluginIds.includes(app.id)); + const appPlugins = Object.values(config.apps).filter((app) => !awaitedAppPluginIds.includes(app.id)); + + preloadPlugins(appPlugins, extensionsRegistry, exposedComponentsRegistry); + await preloadPlugins( + awaitedAppPlugins, + extensionsRegistry, + exposedComponentsRegistry, + 'frontend_awaited_plugins_preload' + ); + } + + setPluginExtensionGetter(createPluginExtensionsGetter(extensionsRegistry)); + setPluginExtensionsHook(createUsePluginExtensions(extensionsRegistry)); + setPluginComponentHook(createUsePluginComponent(exposedComponentsRegistry)); // initialize chrome service const queryParams = locationService.getSearchObject(); const chromeService = new AppChromeService(); const keybindingsService = new KeybindingSrv(locationService, chromeService); + const newAssetsChecker = new NewFrontendAssetsChecker(); + newAssetsChecker.start(); // Read initial kiosk mode from url at app startup chromeService.setKioskModeFromUrl(queryParams.kiosk); @@ -249,20 +240,9 @@ export class GrafanaApp { chrome: chromeService, keybindings: keybindingsService, config, + newAssetsChecker, }; - - dispatchFnEvent({ - isLoading: false, - isError: false, - isIdeal: false, - }); } catch (error) { - dispatchFnEvent({ - isLoading: false, - isError: true, - error, - isIdeal: false, - }); console.error('Failed to start Grafana', error); window.__grafana_load_failed(); } finally { @@ -288,7 +268,7 @@ function initEchoSrv() { window.addEventListener('load', (e) => { const loadMetricName = 'frontend_boot_load_time_seconds'; - // Metrics below are marked in public/views/index-template.html + // Metrics below are marked in public/views/index.html const jsLoadMetricName = 'frontend_boot_js_done_time_seconds'; const cssLoadMetricName = 'frontend_boot_css_time_seconds'; @@ -348,6 +328,7 @@ function initEchoSrv() { user: config.bootData.user, sdkUrl: config.rudderstackSdkUrl, configUrl: config.rudderstackConfigUrl, + integrationsUrl: config.rudderstackIntegrationsUrl, buildInfo: config.buildInfo, }) ); diff --git a/public/app/fn_dashboard.ts b/public/app/fn_dashboard.ts index 04a8957f10e18..6948289e4a479 100644 --- a/public/app/fn_dashboard.ts +++ b/public/app/fn_dashboard.ts @@ -7,7 +7,7 @@ config.featureToggles = { publicDashboards: true, }; interface FnData { - themePaths: { + assets: { light: string; dark: string; }; @@ -19,8 +19,8 @@ declare global { } } -config.isPublicDashboardView = false; -config.bootData.themePaths = window.fnData.themePaths; +// config.isPublicDashboardView = false; +config.bootData.assets = window.fnData.assets; export const { bootstrap, mount, unmount, update, afterMount, afterUnmount, beforeLoad, beforeMount, beforeUnmount } = createMfe.create(FNDashboard); diff --git a/public/app/plugins/datasource/cloudwatch/Search.tsx b/public/app/plugins/datasource/cloudwatch/Search.tsx deleted file mode 100644 index e7af681ffe120..0000000000000 --- a/public/app/plugins/datasource/cloudwatch/Search.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { debounce } from 'lodash'; -import React, { useEffect, useMemo, useState } from 'react'; - -import { Icon, Input, useStyles2 } from '@grafana/ui'; - -import getStyles from './components/styles'; - -// TODO: consider moving search into grafana/ui, this is mostly the same as that in azure monitor -const Search = ({ searchFn, searchPhrase }: { searchPhrase: string; searchFn: (searchPhrase: string) => void }) => { - const [searchFilter, setSearchFilter] = useState(searchPhrase); - const styles = useStyles2(getStyles); - - const debouncedSearch = useMemo(() => debounce(searchFn, 600), [searchFn]); - - useEffect(() => { - return () => { - // Stop the invocation of the debounced function after unmounting - debouncedSearch?.cancel(); - }; - }, [debouncedSearch]); - - return ( - } - value={searchFilter} - onChange={(event) => { - const searchPhrase = event.currentTarget.value; - setSearchFilter(searchPhrase); - debouncedSearch(searchPhrase); - }} - placeholder="search by log group name prefix" - /> - ); -}; - -export default Search; diff --git a/public/app/plugins/datasource/cloudwatch/components/Account.test.tsx b/public/app/plugins/datasource/cloudwatch/components/Account.test.tsx index e2803524fd1ac..c2e420e21b100 100644 --- a/public/app/plugins/datasource/cloudwatch/components/Account.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Account.test.tsx @@ -1,5 +1,4 @@ import { render, screen } from '@testing-library/react'; -import React from 'react'; import selectEvent from 'react-select-event'; import { Account } from './Account'; diff --git a/public/app/plugins/datasource/cloudwatch/components/Account.tsx b/public/app/plugins/datasource/cloudwatch/components/Account.tsx index 57cde6ac83aa8..8078e752db1a1 100644 --- a/public/app/plugins/datasource/cloudwatch/components/Account.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Account.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import { useMemo } from 'react'; import { SelectableValue } from '@grafana/data'; import { EditorField } from '@grafana/experimental'; diff --git a/public/app/plugins/datasource/cloudwatch/components/Search.test.tsx b/public/app/plugins/datasource/cloudwatch/components/Search.test.tsx deleted file mode 100644 index 6312770e21a8e..0000000000000 --- a/public/app/plugins/datasource/cloudwatch/components/Search.test.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -// eslint-disable-next-line lodash/import-scope -import lodash from 'lodash'; -import React from 'react'; - -import Search from '../Search'; - -const defaultProps = { - searchPhrase: '', - searchFn: jest.fn(), -}; -const originalDebounce = lodash.debounce; - -describe('Search', () => { - beforeEach(() => { - lodash.debounce = jest.fn().mockImplementation((fn) => { - fn.cancel = () => {}; - return fn; - }); - }); - afterEach(() => { - lodash.debounce = originalDebounce; - }); - it('displays the search phrase passed in if it exists', async () => { - render(); - expect(await screen.findByDisplayValue('testPhrase')).toBeInTheDocument(); - }); - - it('displays placeholder text if search phrase is not passed in', async () => { - render(); - expect(await screen.findByPlaceholderText('search by log group name prefix')).toBeInTheDocument(); - }); - - it('calls a debounced version of searchFn when typed in', async () => { - const searchFn = jest.fn(); - render(); - await userEvent.type(await screen.findByLabelText('log group search'), 'something'); - expect(searchFn).toBeCalledWith('s'); - expect(searchFn).toHaveBeenLastCalledWith('something'); - }); -}); diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/ConfigEditor.tsx b/public/app/plugins/datasource/fifemon-graphql-datasource/ConfigEditor.tsx deleted file mode 100644 index 0ab28977f86b6..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/ConfigEditor.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { DataSourceHttpSettings } from '@grafana/ui'; -import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; -import { MyDataSourceOptions } from './types'; - -export type Props = DataSourcePluginOptionsEditorProps; -export const ConfigEditor = (props: Props) => { - const { options, onOptionsChange } = props; - - return ( - <> - - - ); -}; diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/DataSource.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/DataSource.ts deleted file mode 100644 index 64dbf71c637ac..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/DataSource.ts +++ /dev/null @@ -1,360 +0,0 @@ -import defaults from 'lodash/defaults'; - -import { - AnnotationEvent, - DataQueryRequest, - DataQueryResponse, - DataSourceApi, - MetricFindValue, - DataSourceInstanceSettings, - ScopedVars, - TimeRange, - dateTime, - MutableDataFrame, - FieldType, - DataFrame, -} from '@grafana/data'; - -import { - MyQuery, - MyDataSourceOptions, - defaultQuery, - MyVariableQuery, - MultiValueVariable, - TextValuePair, -} from './types'; -import { dateTime, MutableDataFrame, FieldType, DataFrame } from '@grafana/data'; -import { getTemplateSrv } from '@grafana/runtime'; -import _ from 'lodash'; -import { isEqual } from 'lodash'; -import { flatten, isRFC3339_ISO6801 } from './util'; - -const supportedVariableTypes = ['constant', 'custom', 'query', 'textbox']; - -export class DataSource extends DataSourceApi { - basicAuth: string | undefined; - withCredentials: boolean | undefined; - url: string | undefined; - - constructor(instanceSettings: DataSourceInstanceSettings, private backendSrv: any) { - super(instanceSettings); - this.basicAuth = instanceSettings.basicAuth; - this.withCredentials = instanceSettings.withCredentials; - this.url = instanceSettings.url; - } - - private request(data: string) { - const options: any = { - url: this.url, - method: 'POST', - data: { - query: data, - }, - }; - - if (this.basicAuth || this.withCredentials) { - options.withCredentials = true; - } - if (this.basicAuth) { - options.headers = { - Authorization: this.basicAuth, - }; - } - - return this.backendSrv.datasourceRequest(options); - } - - private postQuery(query: Partial, payload: string) { - return this.request(payload) - .then((results: any) => { - return { query, results }; - }) - .catch((err: any) => { - if (err.data && err.data.error) { - throw { - message: 'GraphQL error: ' + err.data.error.reason, - error: err.data.error, - }; - } - - throw err; - }); - } - - private createQuery(query: MyQuery, range: TimeRange | undefined, scopedVars: ScopedVars | undefined = undefined) { - let payload = getTemplateSrv().replace(query.queryText, { - ...scopedVars, - timeFrom: { text: 'from', value: range?.from.valueOf() }, - timeTo: { text: 'to', value: range?.to.valueOf() }, - }); - - //console.log(payload); - return this.postQuery(query, payload); - } - private static getDocs(resultsData: any, dataPath: string): any[] { - if (!resultsData) { - throw 'resultsData was null or undefined'; - } - let data = dataPath.split('.').reduce((d: any, p: any) => { - if (!d) { - return null; - } - return d[p]; - }, resultsData.data); - if (!data) { - const errors: any[] = resultsData.errors; - if (errors && errors.length !== 0) { - throw errors[0]; - } - throw 'Your data path did not exist! dataPath: ' + dataPath; - } - if (resultsData.errors) { - // There can still be errors even if there is data - console.log('Got GraphQL errors:'); - console.log(resultsData.errors); - } - const docs: any[] = []; - let pushDoc = (originalDoc: object) => { - docs.push(flatten(originalDoc)); - }; - if (Array.isArray(data)) { - for (const element of data) { - pushDoc(element); - } - } else { - pushDoc(data); - } - return docs; - } - private static getDataPathArray(dataPathString: string): string[] { - const dataPathArray: string[] = []; - for (const dataPath of dataPathString.split(',')) { - const trimmed = dataPath.trim(); - if (trimmed) { - dataPathArray.push(trimmed); - } - } - if (!dataPathArray) { - throw 'data path is empty!'; - } - return dataPathArray; - } - - async query(options: DataQueryRequest): Promise { - return Promise.all( - options.targets.map((target) => { - return this.createQuery(defaults(target, defaultQuery), options.range, options.scopedVars); - }) - ).then((results: any) => { - const dataFrameArray: DataFrame[] = []; - for (let res of results) { - const dataPathArray: string[] = DataSource.getDataPathArray(res.query.dataPath); - const { timePath, timeFormat, groupBy, aliasBy } = res.query; - const split = groupBy.split(','); - const groupByList: string[] = []; - for (const element of split) { - const trimmed = element.trim(); - if (trimmed) { - groupByList.push(trimmed); - } - } - for (const dataPath of dataPathArray) { - const docs: any[] = DataSource.getDocs(res.results.data, dataPath); - - const dataFrameMap = new Map(); - for (const doc of docs) { - if (timePath in doc) { - doc[timePath] = dateTime(doc[timePath], timeFormat); - } - const identifiers: string[] = []; - for (const groupByElement of groupByList) { - identifiers.push(doc[groupByElement]); - } - const identifiersString = identifiers.toString(); - let dataFrame = dataFrameMap.get(identifiersString); - if (!dataFrame) { - // we haven't initialized the dataFrame for this specific identifier that we group by yet - dataFrame = new MutableDataFrame({ fields: [] }); - const generalReplaceObject: any = {}; - for (const fieldName in doc) { - generalReplaceObject['field_' + fieldName] = doc[fieldName]; - } - for (const fieldName in doc) { - let t: FieldType = FieldType.string; - if (fieldName === timePath || isRFC3339_ISO6801(String(doc[fieldName]))) { - t = FieldType.time; - } else if (isNumber(doc[fieldName])) { - t = FieldType.number; - } - let title; - if (identifiers.length !== 0) { - // if we have any identifiers - title = identifiersString + '_' + fieldName; - } else { - title = fieldName; - } - if (aliasBy) { - title = aliasBy; - const replaceObject = { ...generalReplaceObject }; - replaceObject['fieldName'] = fieldName; - for (const replaceKey in replaceObject) { - const replaceValue = replaceObject[replaceKey]; - const regex = new RegExp('\\$' + replaceKey, 'g'); - title = title.replace(regex, replaceValue); - } - title = getTemplateSrv().replace(title, options.scopedVars); - } - dataFrame.addField({ - name: fieldName, - type: t, - config: { displayName: title }, - // @ts-ignore - }).parse = (v: any) => { - return v || ''; - }; - } - dataFrameMap.set(identifiersString, dataFrame); - } - - dataFrame.add(doc); - } - for (const dataFrame of dataFrameMap.values()) { - dataFrameArray.push(dataFrame); - } - } - } - return { data: dataFrameArray }; - }); - } - annotationQuery(options: any): Promise { - const query = defaults(options.annotation, defaultQuery); - return Promise.all([this.createQuery(query, options.range)]).then((results: any) => { - const r: AnnotationEvent[] = []; - for (const res of results) { - const { timePath, endTimePath, timeFormat } = res.query; - const dataPathArray: string[] = DataSource.getDataPathArray(res.query.dataPath); - for (const dataPath of dataPathArray) { - const docs: any[] = DataSource.getDocs(res.results.data, dataPath); - for (const doc of docs) { - const annotation: AnnotationEvent = {}; - if (timePath in doc) { - annotation.time = dateTime(doc[timePath], timeFormat).valueOf(); - } - if (endTimePath in doc) { - annotation.isRegion = true; - annotation.timeEnd = dateTime(doc[endTimePath], timeFormat).valueOf(); - } - let title = query.annotationTitle; - let text = query.annotationText; - let tags = query.annotationTags; - for (const fieldName in doc) { - const fieldValue = doc[fieldName]; - const replaceKey = 'field_' + fieldName; - const regex = new RegExp('\\$' + replaceKey, 'g'); - title = title.replace(regex, fieldValue); - text = text.replace(regex, fieldValue); - tags = tags.replace(regex, fieldValue); - } - - annotation.title = title; - annotation.text = text; - const tagsList: string[] = []; - for (const element of tags.split(',')) { - const trimmed = element.trim(); - if (trimmed) { - tagsList.push(trimmed); - } - } - annotation.tags = tagsList; - r.push(annotation); - } - } - } - return r; - }); - } - - testDatasource() { - const q = `{ - __schema{ - queryType{name} - } - }`; - return this.postQuery(defaultQuery, q).then( - (res: any) => { - if (res.errors) { - console.log(res.errors); - return { - status: 'error', - message: 'GraphQL Error: ' + res.errors[0].message, - }; - } - return { - status: 'success', - message: 'Success', - }; - }, - (err: any) => { - console.log(err); - return { - status: 'error', - message: 'HTTP Response ' + err.status + ': ' + err.statusText, - }; - } - ); - } - - async metricFindQuery(query: MyVariableQuery, options?: any) { - const metricFindValues: MetricFindValue[] = []; - - query = defaults(query, defaultQuery); - - let payload = query.queryText; - payload = getTemplateSrv().replace(payload, { ...this.getVariables }); - - const response = await this.postQuery(query, payload); - - const docs: any[] = DataSource.getDocs(response.results.data, query.dataPath); - - for (const doc of docs) { - if ('__text' in doc && '__value' in doc) { - metricFindValues.push({ text: doc['__text'], value: doc['__value'] }); - } else { - for (const fieldName in doc) { - metricFindValues.push({ text: doc[fieldName] }); - } - } - } - - return metricFindValues; - } - - getVariables() { - const variables: { [id: string]: TextValuePair } = {}; - Object.values(getTemplateSrv().getVariables()).forEach((variable) => { - if (!supportedVariableTypes.includes(variable.type)) { - console.warn(`Variable of type "${variable.type}" is not supported`); - - return; - } - - const supportedVariable = variable as MultiValueVariable; - - let variableValue = supportedVariable.current.value; - if (variableValue === '$__all' || isEqual(variableValue, ['$__all'])) { - if (supportedVariable.allValue === null || supportedVariable.allValue === '') { - variableValue = supportedVariable.options.slice(1).map((textValuePair) => textValuePair.value); - } else { - variableValue = supportedVariable.allValue; - } - } - - variables[supportedVariable.id] = { - text: supportedVariable.current.text, - value: variableValue, - }; - }); - - return variables; - } -} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts deleted file mode 100644 index 0b8a9c3aa1d8b..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/FN_DataSource.ts +++ /dev/null @@ -1,366 +0,0 @@ -import _ from 'lodash'; -import { isEqual } from 'lodash'; -import defaults from 'lodash/defaults'; - -import { - AnnotationEvent, - AnnotationQueryRequest, - DataQueryRequest, - DataQueryResponse, - MetricFindValue, - DataSourceInstanceSettings, - ScopedVars, - TimeRange, -} from '@grafana/data'; -import { dateTime, MutableDataFrame, FieldType, DataFrame } from '@grafana/data'; -import { getTemplateSrv, DataSourceWithBackend } from '@grafana/runtime'; -import { BackendSrv, getBackendSrv } from 'app/core/services/backend_srv'; - -import { BackendSrvRequest } from '../../../../../packages/grafana-runtime/src/services/backendSrv'; - -import { - MyQuery, - MyDataSourceOptions, - defaultQuery, - MyVariableQuery, - MultiValueVariable, - TextValuePair, -} from './types'; -import { flatten, isRFC3339_ISO6801 } from './util'; - -const supportedVariableTypes = ['constant', 'custom', 'query', 'textbox']; - -export class FN_DataSource extends DataSourceWithBackend { - basicAuth: string | undefined; - withCredentials: boolean | undefined; - url: string | undefined; - backendSrv: BackendSrv; - - constructor(instanceSettings: DataSourceInstanceSettings) { - super(instanceSettings); - this.basicAuth = instanceSettings.basicAuth; - this.withCredentials = instanceSettings.withCredentials; - - console.log({instanceSettings}) - const url = instanceSettings.jsonData["connection.url"] - // const url = "http://localhost:8081/api/query" - this.url = url; - - this.backendSrv = getBackendSrv(); - } - - private request(data: string) { - const options: BackendSrvRequest = { - url: this.url as string, - method: 'POST', - data: { - query: data, - }, - }; - - if (this.basicAuth || this.withCredentials) { - options.withCredentials = true; - } - - if (this.basicAuth) { - options.headers = { - Authorization: this.basicAuth, - }; - } - - return this.backendSrv.datasourceRequest(options); - } - - private postQuery(query: Partial, payload: string) { - return this.request(payload) - .then((results: any) => { - return { query, results }; - }) - .catch((err: any) => { - if (err.data && err.data.error) { - throw { - message: 'GraphQL error: ' + err.data.error.reason, - error: err.data.error, - }; - } - - throw err; - }); - } - - private createQuery(query: MyQuery, range: TimeRange | undefined, scopedVars: ScopedVars | undefined = undefined) { - let payload = getTemplateSrv().replace(query.queryText, { - ...scopedVars, - timeFrom: { text: 'from', value: range?.from.valueOf() }, - timeTo: { text: 'to', value: range?.to.valueOf() }, - }); - - //console.log(payload); - return this.postQuery(query, payload); - } - private static getDocs(resultsData: any, dataPath: string): any[] { - if (!resultsData) { - throw 'resultsData was null or undefined'; - } - let data = dataPath.split('.').reduce((d: any, p: any) => { - if (!d) { - return null; - } - return d[p]; - }, resultsData.data); - if (!data) { - const errors: any[] = resultsData.errors; - if (errors && errors.length !== 0) { - throw errors[0]; - } - throw 'Your data path did not exist! dataPath: ' + dataPath; - } - if (resultsData.errors) { - // There can still be errors even if there is data - console.log('Got GraphQL errors:'); - console.log(resultsData.errors); - } - const docs: any[] = []; - let pushDoc = (originalDoc: object) => { - docs.push(flatten(originalDoc)); - }; - if (Array.isArray(data)) { - for (const element of data) { - pushDoc(element); - } - } else { - pushDoc(data); - } - return docs; - } - private static getDataPathArray(dataPathString: string): string[] { - const dataPathArray: string[] = []; - for (const dataPath of dataPathString.split(',')) { - const trimmed = dataPath.trim(); - if (trimmed) { - dataPathArray.push(trimmed); - } - } - if (!dataPathArray) { - throw 'data path is empty!'; - } - return dataPathArray; - } - - async query(options: DataQueryRequest): Promise { - return Promise.all( - options.targets.map((target) => { - return this.createQuery(defaults(target, defaultQuery), options.range, options.scopedVars); - }) - ).then((results: any) => { - const dataFrameArray: DataFrame[] = []; - for (let res of results) { - const dataPathArray: string[] = FN_DataSource.getDataPathArray(res.query.dataPath); - const { timePath, timeFormat, groupBy, aliasBy } = res.query; - const split = groupBy.split(','); - const groupByList: string[] = []; - for (const element of split) { - const trimmed = element.trim(); - if (trimmed) { - groupByList.push(trimmed); - } - } - for (const dataPath of dataPathArray) { - const docs: any[] = FN_DataSource.getDocs(res.results.data, dataPath); - - const dataFrameMap = new Map(); - for (const doc of docs) { - if (timePath in doc) { - doc[timePath] = dateTime(doc[timePath], timeFormat); - } - const identifiers: string[] = []; - for (const groupByElement of groupByList) { - identifiers.push(doc[groupByElement]); - } - const identifiersString = identifiers.toString(); - let dataFrame = dataFrameMap.get(identifiersString); - if (!dataFrame) { - // we haven't initialized the dataFrame for this specific identifier that we group by yet - dataFrame = new MutableDataFrame({ fields: [] }); - const generalReplaceObject: any = {}; - for (const fieldName in doc) { - generalReplaceObject['field_' + fieldName] = doc[fieldName]; - } - for (const fieldName in doc) { - let t: FieldType = FieldType.string; - if (fieldName === timePath || isRFC3339_ISO6801(String(doc[fieldName]))) { - t = FieldType.time; - } else if (_.isNumber(doc[fieldName])) { - t = FieldType.number; - } - let title; - if (identifiers.length !== 0) { - // if we have any identifiers - title = identifiersString + '_' + fieldName; - } else { - title = fieldName; - } - if (aliasBy) { - title = aliasBy; - const replaceObject = { ...generalReplaceObject }; - replaceObject['fieldName'] = fieldName; - for (const replaceKey in replaceObject) { - const replaceValue = replaceObject[replaceKey]; - const regex = new RegExp('\\$' + replaceKey, 'g'); - title = title.replace(regex, replaceValue); - } - title = getTemplateSrv().replace(title, options.scopedVars); - } - dataFrame.addField({ - name: fieldName, - type: t, - config: { displayName: title }, - }).parse = (v: any) => { - return v || ''; - }; - } - dataFrameMap.set(identifiersString, dataFrame); - } - - dataFrame.add(doc); - } - for (const dataFrame of dataFrameMap.values()) { - dataFrameArray.push(dataFrame); - } - } - } - return { data: dataFrameArray }; - }); - } - annotationQuery(options: AnnotationQueryRequest): Promise { - const query = defaults(options.annotation, defaultQuery); - return Promise.all([this.createQuery(query, options.range)]).then((results: any) => { - const r: AnnotationEvent[] = []; - for (const res of results) { - const { timePath, endTimePath, timeFormat } = res.query; - const dataPathArray: string[] = FN_DataSource.getDataPathArray(res.query.dataPath); - for (const dataPath of dataPathArray) { - const docs: any[] = FN_DataSource.getDocs(res.results.data, dataPath); - for (const doc of docs) { - const annotation: AnnotationEvent = {}; - if (timePath in doc) { - annotation.time = dateTime(doc[timePath], timeFormat).valueOf(); - } - if (endTimePath in doc) { - annotation.isRegion = true; - annotation.timeEnd = dateTime(doc[endTimePath], timeFormat).valueOf(); - } - let title = query.annotationTitle; - let text = query.annotationText; - let tags = query.annotationTags; - for (const fieldName in doc) { - const fieldValue = doc[fieldName]; - const replaceKey = 'field_' + fieldName; - const regex = new RegExp('\\$' + replaceKey, 'g'); - title = title.replace(regex, fieldValue); - text = text.replace(regex, fieldValue); - tags = tags.replace(regex, fieldValue); - } - - annotation.title = title; - annotation.text = text; - const tagsList: string[] = []; - for (const element of tags.split(',')) { - const trimmed = element.trim(); - if (trimmed) { - tagsList.push(trimmed); - } - } - annotation.tags = tagsList; - r.push(annotation); - } - } - } - return r; - }); - } - - testDatasource() { - const q = `{ - __schema{ - queryType{name} - } - }`; - return this.postQuery(defaultQuery, q).then( - (res: any) => { - if (res.errors) { - console.log(res.errors); - return { - status: 'error', - message: 'GraphQL Error: ' + res.errors[0].message, - }; - } - return { - status: 'success', - message: 'Success', - }; - }, - (err: any) => { - console.log(err); - return { - status: 'error', - message: 'HTTP Response ' + err.status + ': ' + err.statusText, - }; - } - ); - } - - async metricFindQuery(query: MyVariableQuery, options?: any) { - const metricFindValues: MetricFindValue[] = []; - - query = defaults(query, defaultQuery); - - let payload = query.queryText; - payload = getTemplateSrv().replace(payload, { ...this.getVariables }); - - const response = await this.postQuery(query, payload); - - const docs: any[] = FN_DataSource.getDocs(response.results.data, query.dataPath); - - for (const doc of docs) { - if ('__text' in doc && '__value' in doc) { - metricFindValues.push({ text: doc['__text'], value: doc['__value'] }); - } else { - for (const fieldName in doc) { - metricFindValues.push({ text: doc[fieldName] }); - } - } - } - - return metricFindValues; - } - - getVariables() { - const variables: { [id: string]: TextValuePair } = {}; - Object.values(getTemplateSrv().getVariables()).forEach((variable) => { - if (!supportedVariableTypes.includes(variable.type)) { - console.warn(`Variable of type "${variable.type}" is not supported`); - - return; - } - - const supportedVariable = variable as MultiValueVariable; - - let variableValue = supportedVariable.current.value; - if (variableValue === '$__all' || isEqual(variableValue, ['$__all'])) { - if (supportedVariable.allValue === null || supportedVariable.allValue === '') { - variableValue = supportedVariable.options.slice(1).map((textValuePair) => textValuePair.value); - } else { - variableValue = supportedVariable.allValue; - } - } - - variables[supportedVariable.id] = { - text: supportedVariable.current.text, - value: variableValue, - }; - }); - - return variables; - } -} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/QueryEditor.tsx b/public/app/plugins/datasource/fifemon-graphql-datasource/QueryEditor.tsx deleted file mode 100644 index 4ed8a4f4e7c2a..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/QueryEditor.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import defaults from 'lodash/defaults'; - -import React, { PureComponent, ChangeEvent } from 'react'; -import { QueryEditorProps } from '@grafana/data'; -import { LegacyForms, QueryField, Icon } from '@grafana/ui'; -import { FN_DataSource } from './FN_DataSource'; -import { MyQuery, MyDataSourceOptions, defaultQuery } from './types'; - -type Props = QueryEditorProps; - -interface State {} - -export class QueryEditor extends PureComponent { - onComponentDidMount() {} - - onChangeQuery = (value: string, override?: boolean) => { - const { onChange, query } = this.props; - if (onChange) { - onChange({ ...query, queryText: value }); - } - }; - - onDataPathTextChange = (event: ChangeEvent) => { - const { onChange, query } = this.props; - onChange({ ...query, dataPath: event.target.value }); - }; - onTimePathTextChange = (event: ChangeEvent) => { - const { onChange, query } = this.props; - onChange({ ...query, timePath: event.target.value }); - }; - onTimeFormatTextChange = (event: ChangeEvent) => { - const { onChange, query } = this.props; - onChange({ ...query, timeFormat: event.target.value }); - }; - onGroupByTextChange = (event: ChangeEvent) => { - const { onChange, query } = this.props; - onChange({ ...query, groupBy: event.target.value }); - }; - - onAliasByTextChange = (event: ChangeEvent) => { - const { onChange, query } = this.props; - onChange({ ...query, aliasBy: event.target.value }); - }; - - render() { - const query = defaults(this.props.query, defaultQuery); - const { queryText, dataPath, timePath, timeFormat, groupBy, aliasBy } = query; - - return ( - <> - -
- -
-
- -
-
- - Optional time format in moment.js format.  - - - } - /> -
-
- -
-
- -
- - ); - } -} diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/VariableQueryEditor.tsx b/public/app/plugins/datasource/fifemon-graphql-datasource/VariableQueryEditor.tsx deleted file mode 100644 index 9cde921c74813..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/VariableQueryEditor.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { QueryField } from '@grafana/ui'; -import React, { useState } from 'react'; -import { MyQuery } from './types'; - -interface VariableQueryProps { - query: MyQuery; - onChange: (query: MyQuery, definition: string) => void; -} - -export const VariableQueryEditor: React.FC = ({ onChange, query }) => { - const [state, setState] = useState(query); - - const saveQuery = () => { - onChange(state, `${state.queryText} (${state.dataPath})`); - }; - - const onChangeQuery = (value: string, override?: boolean) => - setState({ - ...state, - queryText: value, - }); - - const handleChange = (event: React.FormEvent) => - setState({ - ...state, - [event.currentTarget.name]: event.currentTarget.value, - }); - - return ( - <> -
- Data Path - -
-
- Query - -
- - ); -}; diff --git a/public/app/plugins/datasource/fifemon-graphql-datasource/module.ts b/public/app/plugins/datasource/fifemon-graphql-datasource/module.ts deleted file mode 100644 index 9da530c68e2cd..0000000000000 --- a/public/app/plugins/datasource/fifemon-graphql-datasource/module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { DataSourcePlugin } from '@grafana/data'; -import { FN_DataSource } from './FN_DataSource'; -import { ConfigEditor } from './ConfigEditor'; -import { QueryEditor } from './QueryEditor'; -import { MyQuery, MyDataSourceOptions } from './types'; -import { GraphQLAnnotationsQueryCtrl } from './GraphQLAnnotationsQueryCtrl'; -import { VariableQueryEditor } from './VariableQueryEditor'; - -export const plugin = new DataSourcePlugin(FN_DataSource) - .setConfigEditor(ConfigEditor) - .setAnnotationQueryCtrl(GraphQLAnnotationsQueryCtrl) - .setQueryEditor(QueryEditor) - .setVariableQueryEditor(VariableQueryEditor); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/ConfigEditor.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/ConfigEditor.tsx index 92b4e051d5da2..77e7c669b4c2e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/ConfigEditor.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/ConfigEditor.tsx @@ -1,12 +1,14 @@ -import React, { PureComponent } from 'react'; +import { PureComponent } from 'react'; + //import '@emotion/react'; -import { TabsBar, Tab, TabContent, IconName } from '@grafana/ui'; import { DataSourcePluginOptionsEditorProps, SelectableValue, KeyValue } from '@grafana/data'; -import { DruidSettings, DruidSecureSettings } from './types'; +import { TabsBar, Tab, TabContent, IconName } from '@grafana/ui'; + import { DruidConnectionSettings } from './configuration/ConnectionSettings'; import { ConnectionSettingsOptions } from './configuration/ConnectionSettings/types'; import { DruidQueryDefaultSettings } from './configuration/QuerySettings'; import { QuerySettingsOptions } from './configuration/QuerySettings/types'; +import { DruidSettings, DruidSecureSettings } from './types'; enum Tabs { Connection, diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/DruidDataSource.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/DruidDataSource.ts index 065121cc2c7dd..336cec3440376 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/DruidDataSource.ts +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/DruidDataSource.ts @@ -54,25 +54,28 @@ export class DruidDataSource extends DataSourceWithBackend> = adhocFilters.reduce((acc, filter: AdHocFilter) => { - let operatorKey = filter.operator; + const filterMap: Record> = adhocFilters.reduce( + (acc, filter: AdHocFilter) => { + let operatorKey = filter.operator; - if (filter.operator === '>' || filter.operator === '<') { - operatorKey = '><'; - } + if (filter.operator === '>' || filter.operator === '<') { + operatorKey = '><'; + } - if (!acc[operatorKey]) { - acc[operatorKey] = {}; - } + if (!acc[operatorKey]) { + acc[operatorKey] = {}; + } - if (!acc[operatorKey][filter.key]) { - acc[operatorKey][filter.key] = [filter]; - } else { - acc[operatorKey][filter.key].push(filter); - } - return acc; - // eslint-disable-next-line - }, {} as Record>); + if (!acc[operatorKey][filter.key]) { + acc[operatorKey][filter.key] = [filter]; + } else { + acc[operatorKey][filter.key].push(filter); + } + return acc; + // eslint-disable-next-line + }, + {} as Record> + ); const equalFilterFields = Object.values(filterMap['='] || {}).map(this.getEqualityFilterField); const notEqualFilterFields = Object.values(filterMap['!='] || {}).map(this.getEqualityFilterField); @@ -115,18 +118,21 @@ export class DruidDataSource extends DataSourceWithBackend { - if (Number.isNaN(Number(filter.value))) { - throw Error(`Bound value should be a number. "${filter.value}" is not a number`); - } - if (!acc[filter.operator]) { - acc[filter.operator] = [Number(filter.value)]; - } else { - acc[filter.operator].push(Number(filter.value)); - } - - return acc; - }, {} as Record); + const operatorsMap = filters.reduce( + (acc, filter) => { + if (Number.isNaN(Number(filter.value))) { + throw Error(`Bound value should be a number. "${filter.value}" is not a number`); + } + if (!acc[filter.operator]) { + acc[filter.operator] = [Number(filter.value)]; + } else { + acc[filter.operator].push(Number(filter.value)); + } + + return acc; + }, + {} as Record + ); return this.getBoundFilterObject( operatorsMap['>'] ? String(Math.max(...operatorsMap['>'])) : null, @@ -172,9 +178,11 @@ export class DruidDataSource extends DataSourceWithBackend { - return this.postResource('query-variable', this.applyTemplateVariables(query)).then((response) => { - return response; - }); + return this.postResource('query-variable', this.applyTemplateVariables(query)).then( + (response) => { + return response; + } + ); } async getTagKeys() { @@ -188,7 +196,7 @@ export class DruidDataSource extends DataSourceWithBackend('query-variable', this.applyTemplateVariables(tagKeysQuery as any)); } async getTagValues(options: { key?: string } = {}) { @@ -202,7 +210,7 @@ export class DruidDataSource extends DataSourceWithBackend('query-variable', this.applyTemplateVariables(tagValuesQuery as any)); } } diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/QueryEditor.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/QueryEditor.tsx index 9a3b6f8572c54..bf7bdbada2197 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/QueryEditor.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/QueryEditor.tsx @@ -1,13 +1,15 @@ -import React, { useState } from 'react'; -import { ToolbarButtonRow, ToolbarButton, Drawer } from '@grafana/ui'; -import { QueryEditorProps } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import { useState } from 'react'; + +import { QueryEditorProps } from '@grafana/data'; +import { ToolbarButtonRow, ToolbarButton, Drawer } from '@grafana/ui'; + import { DruidDataSource } from './DruidDataSource'; -import { DruidSettings, DruidQuery } from './types'; -import { DruidQuerySettings } from './configuration/QuerySettings'; -import { QuerySettingsOptions } from './configuration/QuerySettings/types'; import { DruidQueryBuilder } from './builder/'; import { QueryBuilderOptions } from './builder/types'; +import { DruidQuerySettings } from './configuration/QuerySettings'; +import { QuerySettingsOptions } from './configuration/QuerySettings/types'; +import { DruidSettings, DruidQuery } from './types'; interface Props extends QueryEditorProps {} diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/VariableQueryEditor.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/VariableQueryEditor.tsx index 111794e23fd09..d998d98f4a22e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/VariableQueryEditor.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/VariableQueryEditor.tsx @@ -1,11 +1,13 @@ -import React, { useState } from 'react'; -import { ToolbarButtonRow, ToolbarButton, Drawer } from '@grafana/ui'; import { css, cx } from '@emotion/css'; -import { DruidQuery } from './types'; -import { DruidQuerySettings } from './configuration/QuerySettings'; -import { QuerySettingsOptions } from './configuration/QuerySettings/types'; +import { useState } from 'react'; + +import { ToolbarButtonRow, ToolbarButton, Drawer } from '@grafana/ui'; + import { DruidQueryBuilder } from './builder/'; import { QueryBuilderOptions } from './builder/types'; +import { DruidQuerySettings } from './configuration/QuerySettings'; +import { QuerySettingsOptions } from './configuration/QuerySettings/types'; +import { DruidQuery } from './types'; interface Props { query: DruidQuery; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/DruidQueryBuilder.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/DruidQueryBuilder.tsx index 9ca418a9d485a..37cb917cdb4b3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/DruidQueryBuilder.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/DruidQueryBuilder.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import { debounce } from 'lodash'; + import { Query } from './query'; import { QueryBuilderProps } from './types'; -import { debounce } from 'lodash'; export const DruidQueryBuilder = (props: QueryBuilderProps) => { return ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Checkbox.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Checkbox.tsx index 855d3eb5bd477..851b0ba30d2a7 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Checkbox.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Checkbox.tsx @@ -1,7 +1,10 @@ -import React, { ChangeEvent } from 'react'; -import { Checkbox as CheckboxField } from '@grafana/ui'; import { css, cx } from '@emotion/css'; +import { ChangeEvent } from 'react'; + +import { Checkbox as CheckboxField } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; export const Checkbox = (props: QueryBuilderFieldProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Code.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Code.tsx index 0a3502167c027..ba19c253752d9 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Code.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Code.tsx @@ -1,15 +1,16 @@ import { uniqueId } from 'lodash'; -import React from 'react'; +import AceEditor from 'react-ace'; + import { InlineField } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; -import AceEditor from 'react-ace'; import 'ace-builds/src-noconflict/mode-javascript'; import 'ace-builds/src-noconflict/mode-hjson'; import 'ace-builds/src-noconflict/mode-sql'; import 'ace-builds/src-noconflict/theme-twilight'; - interface Props extends QueryBuilderFieldProps { lang: string; } diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/DateInterval.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/DateInterval.tsx index 919712a465194..9f00cfafdfc33 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/DateInterval.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/DateInterval.tsx @@ -1,10 +1,13 @@ -import React, { ChangeEvent } from 'react'; -import { InlineLabel, stylesFactory, useTheme } from '@grafana/ui'; +import { css, cx, injectGlobal } from '@emotion/css'; +import DatePicker from 'react-datepicker'; + import { GrafanaTheme } from '@grafana/data'; +import { InlineLabel, stylesFactory, useTheme } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; -import { css, cx, injectGlobal } from '@emotion/css'; -import DatePicker from 'react-datepicker'; + import 'react-datepicker/dist/react-datepicker.css'; injectGlobal(` @@ -28,8 +31,8 @@ const ISO8601DURATIONPATTERN = new RegExp( const useInterval = (interval = ''): any => { const intervalPartToDate = (part: string): any => { - var date: Date | undefined = undefined; - var datePlaceholder: string | undefined = undefined; + let date: Date | undefined = undefined; + let datePlaceholder: string | undefined = undefined; const d = new Date(part); if (d instanceof Date && !isNaN(d.getFullYear())) { date = d; @@ -47,24 +50,30 @@ export const DateInterval = (props: Props) => { props.options.builder ); - const onStartDateChangeRaw = (event: ChangeEvent) => { - const value = event.target.value; + const onStartDateChangeRaw = (event?: React.MouseEvent | React.KeyboardEvent) => { + const value = event?.currentTarget?.textContent; if (value && value.indexOf('$') !== -1) { onBuilderChange(props, value + '/' + intervalStop); } }; - const onStartDateChange = (date: Date) => { - const value = date.toISOString(); + const onStartDateChange = ( + date: Date | null, + event?: React.MouseEvent | React.KeyboardEvent + ) => { + const value = date?.toISOString(); onBuilderChange(props, value + '/' + intervalStop); }; - const onStopDateChangeRaw = (event: ChangeEvent) => { - const value = event.target.value; + const onStopDateChangeRaw = (event?: React.MouseEvent | React.KeyboardEvent) => { + const value = event?.currentTarget?.textContent; if (value && (value.indexOf('$') !== -1 || ISO8601DURATIONPATTERN.exec(value) !== null)) { onBuilderChange(props, intervalStart + '/' + value); } }; - const onStopDateChange = (date: Date) => { - const value = date.toISOString(); + const onStopDateChange = ( + date: Date | null, + event?: React.MouseEvent | React.KeyboardEvent + ) => { + const value = date?.toISOString(); onBuilderChange(props, intervalStart + '/' + value); }; const { label, description, format, time } = props; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/DateTime.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/DateTime.tsx index c3992d0794145..c9b4f931b2a97 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/DateTime.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/DateTime.tsx @@ -1,10 +1,13 @@ -import React, { ChangeEvent } from 'react'; -import { InlineLabel, stylesFactory, useTheme } from '@grafana/ui'; +import { css, cx, injectGlobal } from '@emotion/css'; +import DatePicker from 'react-datepicker'; + import { GrafanaTheme } from '@grafana/data'; +import { InlineLabel, stylesFactory, useTheme } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; -import { css, cx, injectGlobal } from '@emotion/css'; -import DatePicker from 'react-datepicker'; + import 'react-datepicker/dist/react-datepicker.css'; injectGlobal(` @@ -22,8 +25,8 @@ interface Props extends QueryBuilderFieldProps { } const useDate = (value = ''): any => { - var date: Date | undefined = undefined; - var datePlaceholder: string | undefined = undefined; + let date: Date | undefined = undefined; + let datePlaceholder: string | undefined = undefined; const d = new Date(value); if (d instanceof Date && !isNaN(d.getFullYear())) { date = d; @@ -35,14 +38,19 @@ const useDate = (value = ''): any => { export const DateTime = (props: Props) => { const [date, datePlaceholder] = useDate(props.options.builder); - const onDateChangeRaw = (event: ChangeEvent) => { - const value = event.target.value; + const onDateChangeRaw = (event?: React.MouseEvent | React.KeyboardEvent) => { + const value = event?.currentTarget?.textContent; if (value && value.indexOf('$') !== -1) { onBuilderChange(props, value); } }; - const onDateChange = (date: Date) => { - onBuilderChange(props, date.toISOString()); + const onDateChange = ( + date: Date | null, + event?: React.MouseEvent | React.KeyboardEvent + ) => { + if (date) { + onBuilderChange(props, date.toISOString()); + } }; const { label, description, format, time } = props; const theme = useTheme(); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Input.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Input.tsx index 0bfba72904f10..7f7543e690a43 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Input.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Input.tsx @@ -1,6 +1,9 @@ -import React, { ChangeEvent } from 'react'; +import { ChangeEvent } from 'react'; + import { Input as InputField, InlineField } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; interface Props extends QueryBuilderFieldProps { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/KeyValue.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/KeyValue.tsx index b264f02191bc5..72139ae83a82e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/KeyValue.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/KeyValue.tsx @@ -1,6 +1,9 @@ -import React, { ChangeEvent } from 'react'; +import { ChangeEvent } from 'react'; + import { Input as InputField, InlineField } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; interface Props extends QueryBuilderFieldProps { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Multiple.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Multiple.tsx index 75c9968b0f922..b1d58c5993139 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Multiple.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Multiple.tsx @@ -1,7 +1,11 @@ -import React, { ComponentType } from 'react'; +import { ComponentType } from 'react'; + import { InlineLabel, Button, Icon } from '@grafana/ui'; -import { QueryBuilderFieldProps } from './types'; + import { QueryBuilderOptions } from '../types'; + +import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange, Row } from '.'; interface Props extends QueryBuilderFieldProps { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Multiselect.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Multiselect.tsx index ec785bc4008d3..4ca1002ed73af 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Multiselect.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Multiselect.tsx @@ -1,7 +1,8 @@ -import React from 'react'; -import { InlineField, MultiSelect as MultiSelectField } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; +import { InlineField, MultiSelect as MultiSelectField } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; interface Props extends QueryBuilderFieldProps { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/QueryBuilderComponent.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/QueryBuilderComponent.tsx index 7b6a50cae7363..7ec69fe87fc3f 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/QueryBuilderComponent.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/QueryBuilderComponent.tsx @@ -1,6 +1,8 @@ +import { cloneDeep } from 'lodash'; + import { QueryBuilderProps, QueryBuilderOptions } from '../types'; + import { QueryBuilderFieldProps, QueryBuilderComponent, QueryComponent, Component } from './types'; -import { cloneDeep } from 'lodash'; export const enum ScopeType { Builder, diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/QueryBuilderComponentSelector.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/QueryBuilderComponentSelector.tsx index 5e8aeef8fdae0..358af59e546c8 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/QueryBuilderComponentSelector.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/QueryBuilderComponentSelector.tsx @@ -1,9 +1,12 @@ -import React, { useState } from 'react'; -import { QueryBuilderComponent, QueryComponent, Component } from './types'; -import { QueryBuilderProps } from '../types'; -import { InlineField, Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; import { cloneDeep } from 'lodash'; +import { useState } from 'react'; + +import { SelectableValue } from '@grafana/data'; +import { InlineField, Select } from '@grafana/ui'; + +import { QueryBuilderProps } from '../types'; + +import { QueryBuilderComponent, QueryComponent, Component } from './types'; const useComponentsRegistry = ( components: Record> @@ -25,8 +28,8 @@ const useComponentKey = ( 'type' in defaultComponent ? defaultComponent.type : 'queryType' in defaultComponent - ? defaultComponent.queryType - : undefined; + ? defaultComponent.queryType + : undefined; } if (key !== undefined) { key = key.toLowerCase(); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Row.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Row.tsx index 5233e76718f1a..48022dd11759b 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Row.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Row.tsx @@ -1,7 +1,8 @@ -import React, { ReactNode } from 'react'; -import { InlineFieldRow, stylesFactory, useTheme } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import { ReactNode } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { InlineFieldRow, stylesFactory, useTheme } from '@grafana/ui'; interface Props { children: ReactNode | ReactNode[]; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Select.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Select.tsx index 692f64092a6cc..d7983b300dded 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Select.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Select.tsx @@ -1,7 +1,8 @@ -import React from 'react'; -import { InlineField, Select as SelectField } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; +import { InlineField, Select as SelectField } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; interface Props extends QueryBuilderFieldProps { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Table.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Table.tsx index 0863613024673..45c1162443916 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Table.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/Table.tsx @@ -1,9 +1,11 @@ -import React from 'react'; +import { uniqueId } from 'lodash'; +import AceEditor from 'react-ace'; + import { InlineField } from '@grafana/ui'; + import { QueryBuilderFieldProps } from './types'; + import { onBuilderChange } from '.'; -import uniqueId from 'lodash/uniqueId'; -import AceEditor from 'react-ace'; import 'ace-builds/src-noconflict/mode-javascript'; import 'ace-builds/src-noconflict/mode-hjson'; import 'ace-builds/src-noconflict/mode-sql'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/types.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/types.ts index 72d234c018919..8136a12ae13bd 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/types.ts +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/abstract/types.ts @@ -1,4 +1,5 @@ import { ComponentType } from 'react'; + import { QueryBuilderProps } from '../types'; export interface QueryBuilderFieldProps extends QueryBuilderProps { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Aggregation.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Aggregation.tsx index 0ad0f01eab20f..c2ec4b75cf7e8 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Aggregation.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Aggregation.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; import { Cardinality, diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Cardinality.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Cardinality.tsx index 125018c6cbd69..9955d84429eaa 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Cardinality.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Cardinality.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Cardinality = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Cardinality); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Count.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Count.tsx index 420b6bebb7886..679bd5e5dd575 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Count.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Count.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Count = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Count); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleAny.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleAny.tsx index a6978ae68ea5b..781e42b58ae23 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleAny.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleAny.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const DoubleAny = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleAny); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleFirst.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleFirst.tsx index f7e32e147a8fb..aa5f0cfc96002 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleFirst.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleFirst.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const DoubleFirst = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleFirst); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleLast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleLast.tsx index 9fea786ce7ae6..d873177056b54 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleLast.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleLast.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const DoubleLast = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleLast); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMax.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMax.tsx index a18ccd11d5685..d8d696e247d80 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMax.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMax.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const DoubleMax = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleMax); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMean.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMean.tsx index 64a98cb3fce53..9a776b20f9e87 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMean.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMean.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const DoubleMean = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleMean); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMin.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMin.tsx index 3de9fc513bfc1..3a86f8d3c2702 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMin.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleMin.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const DoubleMin = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleMin); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleSum.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleSum.tsx index ee1c1b6bc1963..03db09af5ebc8 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleSum.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/DoubleSum.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const DoubleSum = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, DoubleSum); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Filtered.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Filtered.tsx index 3bd649446112f..b492dcab91d07 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Filtered.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Filtered.tsx @@ -1,8 +1,8 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; -import { Aggregation } from './'; import { Filter } from '../filter'; +import { QueryBuilderProps } from '../types'; + +import { Aggregation } from './'; export const Filtered = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Filtered); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatAny.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatAny.tsx index 499d99f836c17..23b0f9e32be9a 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatAny.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatAny.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FloatAny = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FloatAny); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatFirst.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatFirst.tsx index 86da2ae9e01c3..b262bd8490f96 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatFirst.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatFirst.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FloatFirst = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FloatFirst); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatLast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatLast.tsx index 31161c94bb5ff..a0b15e4b5d527 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatLast.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatLast.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FloatLast = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FloatLast); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMax.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMax.tsx index 9454cbc003ace..6868adb1008e0 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMax.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMax.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FloatMax = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FloatMax); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMin.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMin.tsx index 3b425cfd3ff10..ca73eee15ae50 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMin.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatMin.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FloatMin = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FloatMin); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatSum.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatSum.tsx index d7e111992d680..d4e792bd94cac 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatSum.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/FloatSum.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FloatSum = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FloatSum); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Histogram.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Histogram.tsx index b2e8cc605d90b..1abde984a5d82 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Histogram.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Histogram.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Histogram = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Histogram); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/HyperUnique.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/HyperUnique.tsx index b1661a57503f3..ed75a81063eb6 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/HyperUnique.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/HyperUnique.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const HyperUnique = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, HyperUnique); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Javascript.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Javascript.tsx index 45aecca05e79f..1a03f45918670 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Javascript.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/Javascript.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Code, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Javascript = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Javascript); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongAny.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongAny.tsx index e02fa0b16d4bb..061893b485a70 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongAny.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongAny.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const LongAny = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, LongAny); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongFirst.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongFirst.tsx index 32fbfacc37d55..13f032032b934 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongFirst.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongFirst.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const LongFirst = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, LongFirst); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongLast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongLast.tsx index 9cda992b8e59e..5eacae95d88b0 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongLast.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongLast.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const LongLast = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, LongLast); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMax.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMax.tsx index e227875d161d5..b5e1f2ec792b3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMax.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMax.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const LongMax = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, LongMax); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMin.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMin.tsx index 13261d739369f..ecf61198fcddc 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMin.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongMin.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const LongMin = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, LongMin); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongSum.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongSum.tsx index 6523543563810..804dc6d24dcaa 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongSum.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/LongSum.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const LongSum = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, LongSum); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/QuantilesDoublesSketch.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/QuantilesDoublesSketch.tsx index ee5ee8657aa5a..b7c7cba19429c 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/QuantilesDoublesSketch.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/QuantilesDoublesSketch.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const QuantilesDoublesSketch = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, QuantilesDoublesSketch); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringAny.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringAny.tsx index 4c1a7ebb56e8e..01935858b3418 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringAny.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringAny.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const StringAny = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, StringAny); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirst.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirst.tsx index 29d15fcaa348e..6c7ce15a7253a 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirst.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirst.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const StringFirst = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, StringFirst); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirstFolding.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirstFolding.tsx index 06fa49df3d65b..177d163a7adfe 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirstFolding.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringFirstFolding.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const StringFirstFolding = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, StringFirstFolding); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLast.tsx index 67313deed3ec5..42b4f1209c1c9 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLast.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLast.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const StringLast = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, StringLast); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLastFolding.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLastFolding.tsx index 6133e4f9c9a4d..d7de2df4bc422 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLastFolding.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/aggregation/StringLastFolding.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const StringLastFolding = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, StringLastFolding); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Bound.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Bound.tsx index 5c696329b6813..fd6cbe6036647 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Bound.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Bound.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Polygon, Radius, Rectangular } from './'; export const Bound = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Polygon.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Polygon.tsx index e3db137290f84..3117c6401d540 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Polygon.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Polygon.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Polygon = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Polygon); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Radius.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Radius.tsx index 77875ed934dba..378a6daad96a4 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Radius.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Radius.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Radius = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Radius); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Rectangular.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Rectangular.tsx index 66a88e6ed1cdd..08a5a2585fe6a 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Rectangular.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/bound/Rectangular.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Rectangular = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Rectangular); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/DataSource.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/DataSource.tsx index 3dd33257c686d..319926342377e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/DataSource.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/DataSource.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { GlobalTable, Inline, Join, Lookup, Query, Table, Union } from './'; export const DataSource = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/GlobalTable.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/GlobalTable.tsx index e281527d945eb..3257b18c53baa 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/GlobalTable.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/GlobalTable.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const GlobalTable = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, GlobalTable); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Inline.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Inline.tsx index 43a3324c71c95..3caee9c76511b 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Inline.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Inline.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Table, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Inline = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Inline); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Join.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Join.tsx index 3a2166c9ebf2b..68afed706fc1c 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Join.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Join.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { DataSource } from '.'; export const Join = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Lookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Lookup.tsx index b51494de41219..0f3eab5e73ad2 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Lookup.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Lookup.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Lookup = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Lookup); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Query.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Query.tsx index 294b03fd79064..3e1b37ea03b5a 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Query.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Query.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, Row } from '../abstract'; import { Query as QuerySelector } from '../query'; +import { QueryBuilderProps } from '../types'; export const Query = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderProps(props, Query); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Table.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Table.tsx index 73941280d3f75..6068d915e5149 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Table.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Table.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Table = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Table); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Union.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Union.tsx index c81483d54d818..b9ed736e67a83 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Union.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/datasource/Union.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Union = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Union); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Default.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Default.tsx index 4820b352c6ca6..1f17a7ed96f98 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Default.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Default.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Default = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Default); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Dimension.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Dimension.tsx index f7a094d59f60e..179020f96e01e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Dimension.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Dimension.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Default, Extraction, ListFiltered, Lookup, RegisteredLookup, PrefixFiltered, RegexFiltered } from './'; export const Dimension = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Extraction.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Extraction.tsx index 29624fa54e284..11e414f52ef01 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Extraction.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Extraction.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; export const Extraction = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Extraction); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/ListFiltered.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/ListFiltered.tsx index 5698be26b2ed2..b262901ab11cf 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/ListFiltered.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/ListFiltered.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Dimension } from './Dimension'; export const ListFiltered = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Lookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Lookup.tsx index a3b04badd302a..f258605ec4d74 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Lookup.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/Lookup.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; import { Lookup as LookupExtractor } from '../lookup'; +import { QueryBuilderProps } from '../types'; export const Lookup = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Lookup); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/PrefixFiltered.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/PrefixFiltered.tsx index ce3922b04d39e..e07aac37309ef 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/PrefixFiltered.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/PrefixFiltered.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; import { Dimension } from '../dimension'; +import { QueryBuilderProps } from '../types'; export const PrefixFiltered = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, PrefixFiltered); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegexFiltered.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegexFiltered.tsx index 88fa8bd103358..b7820817bb127 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegexFiltered.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegexFiltered.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; import { Dimension } from '../dimension'; +import { QueryBuilderProps } from '../types'; export const RegexFiltered = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, RegexFiltered); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegisteredLookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegisteredLookup.tsx index 34dbc347199cd..a2afdb35c3626 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegisteredLookup.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/dimension/RegisteredLookup.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const RegisteredLookup = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, RegisteredLookup); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Bucket.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Bucket.tsx index cfe13ee2f5b1c..0f99564b6f9ce 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Bucket.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Bucket.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Bucket = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Bucket); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Cascade.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Cascade.tsx index 8938e3e9be0a3..6a753205bfb4a 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Cascade.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Cascade.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { ExtractionFn } from './'; export const Cascade = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/ExtractionFn.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/ExtractionFn.tsx index 802d132ee28f6..d2ae0202b4f14 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/ExtractionFn.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/ExtractionFn.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Bucket, Cascade, diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Identity.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Identity.tsx index 0f48e6507ed13..c7af24fb0a6b7 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Identity.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Identity.tsx @@ -1,7 +1,9 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + import { InfoBox } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Identity = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, Identity); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Javascript.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Javascript.tsx index 48f85bbc92891..1041466e91656 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Javascript.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Javascript.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Code, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Javascript = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Javascript); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lookup.tsx index 3e9f00150dbaf..7de74988dde59 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lookup.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lookup.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; import { Map } from '../lookup'; +import { QueryBuilderProps } from '../types'; export const Lookup = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Lookup); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lower.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lower.tsx index 7ba9a76ea7109..62f27ea926d60 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lower.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Lower.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Lower = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Lower); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Partial.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Partial.tsx index 637620dfa67de..fd38cf87ff4d0 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Partial.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Partial.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Partial = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Partial); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Regex.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Regex.tsx index b3ba3b3b5ff50..696bb3a6c70e6 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Regex.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Regex.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Regex = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Regex); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/RegisteredLookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/RegisteredLookup.tsx index 188fad052fa66..e9f479ab945ee 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/RegisteredLookup.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/RegisteredLookup.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const RegisteredLookup = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, RegisteredLookup); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/SearchQuery.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/SearchQuery.tsx index 268f572069759..34f8b66753fb7 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/SearchQuery.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/SearchQuery.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, Row } from '../abstract'; import { SearchQuerySpec } from '../searchqueryspec'; +import { QueryBuilderProps } from '../types'; export const SearchQuery = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderProps(props, SearchQuery); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StrLen.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StrLen.tsx index 94e1dbe526c3f..605402d07cfa7 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StrLen.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StrLen.tsx @@ -1,7 +1,9 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + import { InfoBox } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const StrLen = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, StrLen); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StringFormat.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StringFormat.tsx index 83954e2f12711..692225ae27b7b 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StringFormat.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/StringFormat.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const StringFormat = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, StringFormat); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Substring.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Substring.tsx index d2386ea6d9b2d..8f66ae9d47d69 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Substring.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Substring.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Substring = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Substring); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Time.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Time.tsx index 4f5e52fd31c74..be50bc868130d 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Time.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Time.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Time = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Time); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/TimeFormat.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/TimeFormat.tsx index 715c5f67b0b25..ac867cd3c2be8 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/TimeFormat.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/TimeFormat.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; import { Granularity } from '../granularity'; +import { QueryBuilderProps } from '../types'; export const TimeFormat = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, TimeFormat); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Upper.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Upper.tsx index 90f70b42459f2..dd28b8c457ffa 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Upper.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/extractionfn/Upper.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Upper = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Upper); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/And.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/And.tsx index 39cdc0cb48faf..bdc10e10bb612 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/And.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/And.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Filter } from './'; export const And = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Bound.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Bound.tsx index e31dbbd02e125..0970377172802 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Bound.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Bound.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Select, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; export const Bound = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/ColumnComparison.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/ColumnComparison.tsx index f3c315c970204..3bc871eb50e82 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/ColumnComparison.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/ColumnComparison.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; import { Dimension } from '../dimension'; +import { QueryBuilderProps } from '../types'; export const ColumnComparison = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, ColumnComparison); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Expression.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Expression.tsx index 5a073c5c30386..37fab97759fc6 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Expression.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Expression.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; export const Expression = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Extraction.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Extraction.tsx index cb6184856f7c1..d89ceb17a0d49 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Extraction.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Extraction.tsx @@ -1,8 +1,10 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + import { InfoBox } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; export const Extraction = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Extraction); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/False.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/False.tsx index 48ac9821507fe..848955c793dde 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/False.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/False.tsx @@ -1,7 +1,9 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + import { InfoBox } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const False = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, False); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Filter.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Filter.tsx index 725f1d37c199e..ff9f6f264720b 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Filter.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Filter.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { And, Bound, diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/FilterTuning.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/FilterTuning.tsx index f6eac7e2e87dd..69c54e303caf5 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/FilterTuning.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/FilterTuning.tsx @@ -1,7 +1,7 @@ -import React from 'react'; import { InlineLabel } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FilterTuning = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FilterTuning); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/In.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/In.tsx index f7ab648bc75e3..277ed814492d9 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/In.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/In.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; export const In = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Interval.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Interval.tsx index ff574eb4e2a59..43cb27a54e6e3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Interval.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Interval.tsx @@ -1,8 +1,8 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, useScopedQueryBuilderProps, Input, Row } from '../abstract'; -import { Intervals } from '../querysegmentspec'; import { ExtractionFn } from '../extractionfn'; +import { Intervals } from '../querysegmentspec'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; export const Interval = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Javascript.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Javascript.tsx index 1acf0ee883139..e0daebbe26c53 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Javascript.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Javascript.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Code, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; export const Javascript = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Like.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Like.tsx index f4dd4f0d51f61..e826f359769f4 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Like.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Like.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; export const Like = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Not.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Not.tsx index 4bc28fe35e57a..0bf5c93d6546c 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Not.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Not.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Filter } from './'; export const Not = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Or.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Or.tsx index af97580460445..47c138dc773e3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Or.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Or.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Filter } from './'; export const Or = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Regex.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Regex.tsx index 173a0b7a97e1e..57740dec9a147 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Regex.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Regex.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; export const Regex = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Search.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Search.tsx index cf7d202ffe53e..b057ae43e7bb4 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Search.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Search.tsx @@ -1,9 +1,9 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; -import { FilterTuning } from '.'; import { SearchQuerySpec } from '../searchqueryspec'; +import { QueryBuilderProps } from '../types'; + +import { FilterTuning } from '.'; export const Search = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Search); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Selector.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Selector.tsx index 7e8cc25df7ab0..55c40b0e5974c 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Selector.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Selector.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; export const Selector = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Spatial.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Spatial.tsx index 5795528898dcf..db3d0b8a29f6f 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Spatial.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/Spatial.tsx @@ -1,9 +1,9 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { Bound } from '../bound'; import { ExtractionFn } from '../extractionfn'; +import { QueryBuilderProps } from '../types'; + import { FilterTuning } from '.'; -import { Bound } from '../bound'; export const Spatial = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Spatial); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/True.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/True.tsx index a8effcccf5a2d..c3458caf2316e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/True.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/filter/True.tsx @@ -1,7 +1,9 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + import { InfoBox } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const True = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, True); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Duration.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Duration.tsx index b22460dc6a2e5..22519c0a7e5df 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Duration.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Duration.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, DateTime, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Duration = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Duration); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Granularity.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Granularity.tsx index 9291fd84e4867..b06e3a6b58229 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Granularity.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Granularity.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Duration, Period, Simple } from './'; export const Granularity = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Period.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Period.tsx index 0c1740908c57c..5d5daecf4f022 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Period.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Period.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, DateTime, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Period = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Period); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Simple.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Simple.tsx index a964a00e641e1..9f952aed1c268 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Simple.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/granularity/Simple.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { Select, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Simple = (props: QueryBuilderProps) => { const { options, onOptionsChange } = props; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/And.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/And.tsx index f518d81bef22e..ec642e044c059 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/And.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/And.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { HavingSpec } from './'; export const And = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/DimSelector.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/DimSelector.tsx index b3c6f888ec97f..d0ab663dda2b6 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/DimSelector.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/DimSelector.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const DimSelector = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, DimSelector); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/EqualTo.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/EqualTo.tsx index 36fc75b37220d..f42da66064260 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/EqualTo.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/EqualTo.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const EqualTo = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, EqualTo); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Filter.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Filter.tsx index c0e4d4379d1b0..8fd8f087167f4 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Filter.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Filter.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Row } from '../abstract'; import { Filter as FilterField } from '../filter'; +import { QueryBuilderProps } from '../types'; export const Filter = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Filter); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/GreaterThan.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/GreaterThan.tsx index 0ab227f20ed0f..ff91d5ca4865b 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/GreaterThan.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/GreaterThan.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const GreaterThan = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, GreaterThan); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/HavingSpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/HavingSpec.tsx index 2a7e881c68f76..db47275696ef3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/HavingSpec.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/HavingSpec.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { And, DimSelector, EqualTo, Filter, GreaterThan, LessThan, Not, Or } from './'; export const HavingSpec = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/LessThan.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/LessThan.tsx index bf1c4b065e618..8a6c0ec69d5c5 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/LessThan.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/LessThan.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const LessThan = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, LessThan); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Not.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Not.tsx index 47523adbc4d00..fd7e0caee00d9 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Not.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Not.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { HavingSpec } from './'; export const Not = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Or.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Or.tsx index d59456a9135c2..34545f18f9133 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Or.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/havingspec/Or.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { HavingSpec } from './'; export const Or = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/Default.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/Default.tsx index c4283c52c5b12..b6dae727f0ac4 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/Default.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/Default.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { OrderByColumnSpecs } from '.'; export const Default = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/LimitSpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/LimitSpec.tsx index 26ac2e1eccb72..977001c6490a3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/LimitSpec.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/LimitSpec.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Default } from './'; export const LimitSpec = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/OrderByColumnSpecs.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/OrderByColumnSpecs.tsx index 999b882e80509..591e2459ca323 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/OrderByColumnSpecs.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/limitspec/OrderByColumnSpecs.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const OrderByColumnSpecs = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, OrderByColumnSpecs); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Lookup.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Lookup.tsx index 20bdf760be817..7b6b490950c46 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Lookup.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Lookup.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Map } from './'; export const Lookup = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Map.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Map.tsx index 2cc5881c00347..8f4211d226990 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Map.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/lookup/Map.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, KeyValue, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Map = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Map); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Arithmetic.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Arithmetic.tsx index 35d2491300fae..acb5aa99e1be3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Arithmetic.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Arithmetic.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Select, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { PostAggregation } from './.'; export const Arithmetic = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Constant.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Constant.tsx index 8841fb099eae7..618e7337b7a84 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Constant.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Constant.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Constant = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Constant); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleGreatest.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleGreatest.tsx index b27e2ac5d73ce..6f89226074a05 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleGreatest.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleGreatest.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { PostAggregation } from './.'; export const DoubleGreatest = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleLeast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleLeast.tsx index 7bd4a74eaa5d6..b8339627fecc2 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleLeast.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/DoubleLeast.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { PostAggregation } from './.'; export const DoubleLeast = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FieldAccess.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FieldAccess.tsx index a2dcf3767a714..17d06ddd7e045 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FieldAccess.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FieldAccess.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FieldAccess = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FieldAccess); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FinalizingFieldAccess.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FinalizingFieldAccess.tsx index c78e136755aaa..99c1ad863a355 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FinalizingFieldAccess.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/FinalizingFieldAccess.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const FinalizingFieldAccess = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, FinalizingFieldAccess); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/HyperUniqueCardinality.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/HyperUniqueCardinality.tsx index 2434dcc508065..9f72502dde9d5 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/HyperUniqueCardinality.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/HyperUniqueCardinality.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const HyperUniqueCardinality = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, HyperUniqueCardinality); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Javascript.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Javascript.tsx index 53437d9a30a60..61769382e2ca0 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Javascript.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/Javascript.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Code, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Javascript = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Javascript); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongGreatest.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongGreatest.tsx index 506ee66f3565b..02387038f6146 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongGreatest.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongGreatest.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { PostAggregation } from './.'; export const LongGreatest = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongLeast.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongLeast.tsx index 39f1312706d5b..8bc102504e89b 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongLeast.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/LongLeast.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { PostAggregation } from './.'; export const LongLeast = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/PostAggregation.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/PostAggregation.tsx index 40fa4fbac9a5a..797a64faf7a3a 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/PostAggregation.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/PostAggregation.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Arithmetic, Constant, diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/QuantilesDoublesSketchToQuantile.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/QuantilesDoublesSketchToQuantile.tsx index 5dfd1f892a66a..e7127ef42bed6 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/QuantilesDoublesSketchToQuantile.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/postaggregation/QuantilesDoublesSketchToQuantile.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row, QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { FieldAccess, FinalizingFieldAccess, Javascript } from './'; export const QuantilesDoublesSketchToQuantile = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/DatasourceMetadata.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/DatasourceMetadata.tsx index 84b0b3c27fc3d..1c1cda9b6f7f2 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/DatasourceMetadata.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/DatasourceMetadata.tsx @@ -1,7 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, Row } from '../abstract'; import { DataSource } from '../datasource'; +import { QueryBuilderProps } from '../types'; export const DatasourceMetadata = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderProps(props, DatasourceMetadata); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/GroupBy.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/GroupBy.tsx index dc38d247691bb..956e0418df6d7 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/GroupBy.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/GroupBy.tsx @@ -1,15 +1,14 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Multiple, Row } from '../abstract'; +import { Aggregation } from '../aggregation'; import { DataSource } from '../datasource'; import { Dimension } from '../dimension'; -import { LimitSpec } from '../limitspec'; -import { HavingSpec } from '../havingspec'; -import { Granularity } from '../granularity'; import { Filter } from '../filter'; -import { Aggregation } from '../aggregation'; +import { Granularity } from '../granularity'; +import { HavingSpec } from '../havingspec'; +import { LimitSpec } from '../limitspec'; import { PostAggregation } from '../postaggregation'; import { Intervals } from '../querysegmentspec'; +import { QueryBuilderProps } from '../types'; import { VirtualColumn } from '../virtualcolumn'; export const GroupBy = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Json.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Json.tsx index e06fe46f53fdc..ed67df179d0ea 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Json.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Json.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps, QueryBuilderOptions } from '../types'; import { Code, Row } from '../abstract'; +import { QueryBuilderProps, QueryBuilderOptions } from '../types'; export const Json = (props: QueryBuilderProps) => { const options: any = { builder: JSON.stringify(props.options.builder, null, '\t') }; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Query.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Query.tsx index 68bec36d9b832..8deebe96d25c5 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Query.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Query.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { DatasourceMetadata, GroupBy, diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Scan.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Scan.tsx index b7135e60786cb..6aa9b898496b4 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Scan.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Scan.tsx @@ -1,10 +1,9 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Multiple, Input, Select, Row } from '../abstract'; import { DataSource } from '../datasource'; import { Filter } from '../filter'; -import { VirtualColumn } from '../virtualcolumn'; import { Intervals } from '../querysegmentspec'; +import { QueryBuilderProps } from '../types'; +import { VirtualColumn } from '../virtualcolumn'; export const Scan = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Scan); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Search.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Search.tsx index 99632d97280bf..f19b50ae76f6d 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Search.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Search.tsx @@ -1,13 +1,12 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Multiple, Input, Row } from '../abstract'; import { DataSource } from '../datasource'; -import { Granularity } from '../granularity'; +import { Dimension } from '../dimension'; import { Filter } from '../filter'; +import { Granularity } from '../granularity'; import { Intervals } from '../querysegmentspec'; -import { Dimension } from '../dimension'; import { SearchQuerySpec } from '../searchqueryspec'; import { SearchSortSpec } from '../searchsortspec'; +import { QueryBuilderProps } from '../types'; export const Search = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Search); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/SegmentMetadata.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/SegmentMetadata.tsx index dd76f48e34815..7f72d77288ee2 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/SegmentMetadata.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/SegmentMetadata.tsx @@ -1,5 +1,3 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, @@ -12,6 +10,7 @@ import { import { DataSource } from '../datasource'; import { Intervals } from '../querysegmentspec'; import { ToInclude } from '../toinclude'; +import { QueryBuilderProps } from '../types'; export const SegmentMetadata = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, SegmentMetadata); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Sql.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Sql.tsx index bcdc4e718ac19..93dc262da7ab4 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Sql.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Sql.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Code, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Sql = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Sql); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TimeBoundary.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TimeBoundary.tsx index d4ccf8fde0646..5657032231272 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TimeBoundary.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TimeBoundary.tsx @@ -1,9 +1,8 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Select, Row } from '../abstract'; import { DataSource } from '../datasource'; import { Filter } from '../filter'; import { Intervals } from '../querysegmentspec'; +import { QueryBuilderProps } from '../types'; export const TimeBoundary = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, TimeBoundary); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Timeseries.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Timeseries.tsx index cb740b0565e50..d7edc9b1dd3f5 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Timeseries.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/Timeseries.tsx @@ -1,5 +1,3 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, @@ -8,13 +6,14 @@ import { Checkbox, Row, } from '../abstract'; +import { Aggregation } from '../aggregation'; import { DataSource } from '../datasource'; -import { Granularity } from '../granularity'; import { Filter } from '../filter'; -import { Aggregation } from '../aggregation'; +import { Granularity } from '../granularity'; import { PostAggregation } from '../postaggregation'; -import { VirtualColumn } from '../virtualcolumn'; import { Intervals } from '../querysegmentspec'; +import { QueryBuilderProps } from '../types'; +import { VirtualColumn } from '../virtualcolumn'; export const Timeseries = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Timeseries); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TopN.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TopN.tsx index 33e5de5d6dc63..1bdce402d594a 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TopN.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/query/TopN.tsx @@ -1,14 +1,13 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, useScopedQueryBuilderFieldProps, Multiple, Input, Row } from '../abstract'; +import { Aggregation } from '../aggregation'; import { DataSource } from '../datasource'; -import { Intervals } from '../querysegmentspec'; -import { Granularity } from '../granularity'; +import { Dimension } from '../dimension'; import { Filter } from '../filter'; -import { Aggregation } from '../aggregation'; +import { Granularity } from '../granularity'; import { PostAggregation } from '../postaggregation'; -import { Dimension } from '../dimension'; +import { Intervals } from '../querysegmentspec'; import { TopNMetric } from '../topnmetric'; +import { QueryBuilderProps } from '../types'; import { VirtualColumn } from '../virtualcolumn'; export const TopN = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/Intervals.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/Intervals.tsx index 3bd118d67e0a7..5a1f6137e277e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/Intervals.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/Intervals.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Multiple, DateInterval } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Intervals = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Intervals); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/QuerySegmentSpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/QuerySegmentSpec.tsx index 95a483a8c79ab..0ec7ae1f66567 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/QuerySegmentSpec.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/querysegmentspec/QuerySegmentSpec.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Intervals } from './'; export const QuerySegmentSpec = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/All.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/All.tsx index 7a4ddfe5b993c..a71b4239cd7bb 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/All.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/All.tsx @@ -1,7 +1,9 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + import { InfoBox } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const All = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, All); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Contains.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Contains.tsx index 65ecca4c902e8..73e92969f1b4c 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Contains.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Contains.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Contains = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Contains); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Fragment.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Fragment.tsx index 4e5eef1e2f12f..4e23a14c9f3d3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Fragment.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Fragment.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Checkbox, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Fragment = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Fragment); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/InsensitiveContains.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/InsensitiveContains.tsx index 0f3904fea9b72..a2f60f1764122 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/InsensitiveContains.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/InsensitiveContains.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const InsensitiveContains = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, InsensitiveContains); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Regex.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Regex.tsx index 9bb9f16cfc232..152c584ef8355 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Regex.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/Regex.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Regex = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Regex); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/SearchQuerySpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/SearchQuerySpec.tsx index 9f6e1b5b8c26f..be84271327fe2 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/SearchQuerySpec.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchqueryspec/SearchQuerySpec.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { All, Contains, Fragment, InsensitiveContains, Regex } from './'; export const SearchQuerySpec = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/AlphaNumeric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/AlphaNumeric.tsx index 3747411ad1926..04ce7ff7b5834 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/AlphaNumeric.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/AlphaNumeric.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const AlphaNumeric = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, AlphaNumeric); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Lexicographic.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Lexicographic.tsx index b3db709f608ea..8dfcfba3baf44 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Lexicographic.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Lexicographic.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Lexicographic = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, Lexicographic); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Numeric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Numeric.tsx index f6c6edf95f867..9fe299d013c05 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Numeric.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Numeric.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Numeric = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, Numeric); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/SearchSortSpec.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/SearchSortSpec.tsx index e2ba2fb2db62a..d8a2d34bc0347 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/SearchSortSpec.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/SearchSortSpec.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { AlphaNumeric, Lexicographic, Numeric, StrLen, Version } from './'; export const SearchSortSpec = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/StrLen.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/StrLen.tsx index 8f29f727090a7..478c7afb8bf85 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/StrLen.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/StrLen.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const StrLen = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, StrLen); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Version.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Version.tsx index 7636260ab81e3..afea3b851ac3f 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Version.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/searchsortspec/Version.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Version = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, Version); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/All.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/All.tsx index 42fbeb0605f1d..2ff212d2893f0 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/All.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/All.tsx @@ -1,7 +1,9 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + import { InfoBox } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const All = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, All); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/List.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/List.tsx index 7cc9f513de30a..9502b647a0822 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/List.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/List.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Multiple, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const List = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, List); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/None.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/None.tsx index c95f69c9a7d25..15e44326cc7df 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/None.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/None.tsx @@ -1,7 +1,9 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; + import { InfoBox } from '@grafana/ui'; -import { QueryBuilderProps } from '../types'; + import { useQueryBuilderAutoSubmit, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const None = (props: QueryBuilderProps) => { useQueryBuilderAutoSubmit(props, None); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/ToInclude.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/ToInclude.tsx index 592045f8dfdad..7b7b5fca57a7f 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/ToInclude.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/toinclude/ToInclude.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { All, List, None } from './'; export const ToInclude = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/AlphaNumeric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/AlphaNumeric.tsx index 831fd241a37e5..0b78cd8c14b0b 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/AlphaNumeric.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/AlphaNumeric.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const AlphaNumeric = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, AlphaNumeric); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Dimension.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Dimension.tsx index 8d52ea7221d65..725a74d0189d8 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Dimension.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Dimension.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Dimension = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Dimension); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Inverted.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Inverted.tsx index d65499eece148..d324ed4c4c174 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Inverted.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Inverted.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderProps, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { TopNMetric } from './'; export const Inverted = (props: QueryBuilderProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Lexicographic.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Lexicographic.tsx index adef0a4715985..05d8d7a129caa 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Lexicographic.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Lexicographic.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Lexicographic = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Lexicographic); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Numeric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Numeric.tsx index 7578d4a568d4b..12e63f382b905 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Numeric.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/Numeric.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Numeric = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Numeric); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/TopNMetric.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/TopNMetric.tsx index 70acf4ce3dd22..1f59c6dd5f765 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/TopNMetric.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/topnmetric/TopNMetric.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { AlphaNumeric, Dimension, Inverted, Lexicographic, Numeric } from './'; export const TopNMetric = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/Expression.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/Expression.tsx index a47e30d2ae787..649fc8e4b5a9e 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/Expression.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/Expression.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { useScopedQueryBuilderFieldProps, Input, Select, Row } from '../abstract'; +import { QueryBuilderProps } from '../types'; export const Expression = (props: QueryBuilderProps) => { const scopedProps = useScopedQueryBuilderFieldProps(props, Expression); diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/VirtualColumn.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/VirtualColumn.tsx index 902cac659b1ed..b51a8487eee69 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/VirtualColumn.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/builder/virtualcolumn/VirtualColumn.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { QueryBuilderProps } from '../types'; import { QueryBuilderComponentSelector } from '../abstract'; +import { QueryBuilderProps } from '../types'; + import { Expression } from './'; export const VirtualColumn = (props: QueryBuilderProps) => ( diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidAuthSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidAuthSettings.tsx index 7c779833008a9..f65c0d175c740 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidAuthSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidAuthSettings.tsx @@ -1,7 +1,10 @@ -import React, { ChangeEvent } from 'react'; import { css } from '@emotion/css'; +import { ChangeEvent } from 'react'; + import { FieldSet, Field, Switch } from '@grafana/ui'; + import { ConnectionSettingsProps } from './types'; + import { DruidBasicAuthSettings } from './'; export const DruidAuthSettings = (props: ConnectionSettingsProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidBasicAuthSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidBasicAuthSettings.tsx index 6d26b2c9e6a85..1c1058f645fa5 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidBasicAuthSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidBasicAuthSettings.tsx @@ -1,5 +1,7 @@ -import React, { ChangeEvent } from 'react'; +import { ChangeEvent } from 'react'; + import { LegacyForms, FieldSet } from '@grafana/ui'; + import { ConnectionSettingsProps } from './types'; const { FormField, SecretFormField } = LegacyForms; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidConnectionSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidConnectionSettings.tsx index c8b8efd9c0c85..284671f55d917 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidConnectionSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidConnectionSettings.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { DruidHttpSettings, DruidAuthSettings } from './'; import { ConnectionSettingsProps } from './types'; +import { DruidHttpSettings, DruidAuthSettings } from './'; + export const DruidConnectionSettings = (props: ConnectionSettingsProps) => { return ( <> diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidHttpSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidHttpSettings.tsx index de3673ff42f0e..9dbe0fde336e1 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidHttpSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/ConnectionSettings/DruidHttpSettings.tsx @@ -1,4 +1,5 @@ -import React, { ChangeEvent } from 'react'; +import { css } from '@emotion/css'; +import { ChangeEvent } from 'react'; import { LegacyForms, FieldSet, Field, Switch, TagsInput, InlineFormLabel } from '@grafana/ui'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryContextSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryContextSettings.tsx index 7226063cba5aa..c9707e16edda1 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryContextSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryContextSettings.tsx @@ -1,7 +1,9 @@ -import React, { ChangeEvent } from 'react'; -import { InlineLabel, InlineField, InlineFieldRow, Input, Button, Icon, useTheme, stylesFactory } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import { ChangeEvent } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { InlineLabel, InlineField, InlineFieldRow, Input, Button, Icon, useTheme, stylesFactory } from '@grafana/ui'; + import { QuerySettingsProps } from './types'; const useParameters = (props: QuerySettingsProps): any => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryDefaultSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryDefaultSettings.tsx index 080465a14eabc..01732f61c4de3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryDefaultSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryDefaultSettings.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { FieldSet } from '@grafana/ui'; import { css, cx } from '@emotion/css'; -import { DruidQueryRequestSettings, DruidQueryResponseSettings } from './'; + +import { FieldSet } from '@grafana/ui'; + import { QuerySettingsProps } from './types'; +import { DruidQueryRequestSettings, DruidQueryResponseSettings } from './'; + export const DruidQueryDefaultSettings = (props: QuerySettingsProps) => { return ( <> diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryLogSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryLogSettings.tsx index 368bc4c6420a8..48ece537716b8 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryLogSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryLogSettings.tsx @@ -1,7 +1,9 @@ -import React, { ChangeEvent } from 'react'; -import { InlineLabel, InlineFieldRow, InlineField, Input, useTheme, stylesFactory } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import { ChangeEvent } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { InlineLabel, InlineFieldRow, InlineField, Input, useTheme, stylesFactory } from '@grafana/ui'; + import { QuerySettingsProps } from './types'; export const DruidQueryLogSettings = (props: QuerySettingsProps) => { diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryRequestSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryRequestSettings.tsx index 4bd4a37c304ab..1b4a9970771b3 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryRequestSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryRequestSettings.tsx @@ -1,7 +1,9 @@ -import React, { ChangeEvent } from 'react'; +import { ChangeEvent } from 'react'; + import { InlineFieldRow, InlineField, Input } from '@grafana/ui'; -import { QuerySettingsProps } from './types'; + import { DruidQueryContextSettings } from './DruidQueryContextSettings'; +import { QuerySettingsProps } from './types'; export const DruidQueryRequestSettings = (props: QuerySettingsProps) => { const { options, onOptionsChange } = props; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryResponseSettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryResponseSettings.tsx index eb47082b9ce4e..ef748ed362e7f 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryResponseSettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQueryResponseSettings.tsx @@ -1,8 +1,10 @@ -import React, { ChangeEvent } from 'react'; -import { InlineFieldRow, InlineField, InlineSwitch, Select, Input } from '@grafana/ui'; +import { ChangeEvent } from 'react'; + import { SelectableValue } from '@grafana/data'; -import { QuerySettingsProps } from './types'; +import { InlineFieldRow, InlineField, InlineSwitch, Select, Input } from '@grafana/ui'; + import { DruidQueryLogSettings } from './DruidQueryLogSettings'; +import { QuerySettingsProps } from './types'; export const DruidQueryResponseSettings = (props: QuerySettingsProps) => { const { options, onOptionsChange } = props; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQuerySettings.tsx b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQuerySettings.tsx index 007f378e01051..c8f0d53871461 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQuerySettings.tsx +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/configuration/QuerySettings/DruidQuerySettings.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { FieldSet } from '@grafana/ui'; import { css, cx } from '@emotion/css'; -import { DruidQueryRequestSettings, DruidQueryResponseSettings } from './'; + +import { FieldSet } from '@grafana/ui'; + import { QuerySettingsProps } from './types'; +import { DruidQueryRequestSettings, DruidQueryResponseSettings } from './'; + export const DruidQuerySettings = (props: QuerySettingsProps) => { return ( <> diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/module.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/module.ts index e92b9ba61882c..bd82dbb9e2f3b 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/module.ts +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/module.ts @@ -1,6 +1,7 @@ import { DataSourcePlugin } from '@grafana/data'; -import { DruidDataSource } from './DruidDataSource'; + import { ConfigEditor } from './ConfigEditor'; +import { DruidDataSource } from './DruidDataSource'; import { QueryEditor } from './QueryEditor'; import { VariableQueryEditor } from './VariableQueryEditor'; import { DruidQuery, DruidSettings } from './types'; diff --git a/public/app/plugins/datasource/grafadruid-druid-datasource/types.ts b/public/app/plugins/datasource/grafadruid-druid-datasource/types.ts index b5e8da9cc8c46..44902005197b9 100644 --- a/public/app/plugins/datasource/grafadruid-druid-datasource/types.ts +++ b/public/app/plugins/datasource/grafadruid-druid-datasource/types.ts @@ -1,6 +1,7 @@ import { DataQuery, DataSourceJsonData } from '@grafana/data'; -import { QuerySettings } from './configuration/QuerySettings/types'; + import { ConnectionSettings } from './configuration/ConnectionSettings/types'; +import { QuerySettings } from './configuration/QuerySettings/types'; //expr is a workaround: https://github.com/grafana/grafana/issues/30013 export interface DruidQuery extends DataQuery { diff --git a/public/app/plugins/panel/barchart/utils.ts b/public/app/plugins/panel/barchart/utils.ts index 5d8192e260a24..117d43e327aee 100644 --- a/public/app/plugins/panel/barchart/utils.ts +++ b/public/app/plugins/panel/barchart/utils.ts @@ -539,7 +539,10 @@ function getRotationPadding( function getScaleOrientation(orientation: VizOrientation) { if (orientation === VizOrientation.Vertical) { return { - warn: 'No Data', + xOri: ScaleOrientation.Horizontal, + xDir: ScaleDirection.Right, + yOri: ScaleOrientation.Vertical, + yDir: ScaleDirection.Up, }; } diff --git a/public/app/plugins/panel/canvas/Connections.tsx b/public/app/plugins/panel/canvas/Connections.tsx deleted file mode 100644 index e9da09b3959b0..0000000000000 --- a/public/app/plugins/panel/canvas/Connections.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import React from 'react'; - -import { ConnectionPath } from 'app/features/canvas'; -import { ElementState } from 'app/features/canvas/runtime/element'; -import { Scene } from 'app/features/canvas/runtime/scene'; - -import { CONNECTION_ANCHOR_ALT, ConnectionAnchors, CONNECTION_ANCHOR_HIGHLIGHT_OFFSET } from './ConnectionAnchors'; -import { ConnectionSVG } from './ConnectionSVG'; -import { isConnectionSource, isConnectionTarget } from './utils'; - -export class Connections { - scene: Scene; - connectionAnchorDiv?: HTMLDivElement; - connectionSVG?: SVGElement; - connectionLine?: SVGLineElement; - connectionSource?: ElementState; - connectionTarget?: ElementState; - isDrawingConnection?: boolean; - didConnectionLeaveHighlight?: boolean; - - constructor(scene: Scene) { - this.scene = scene; - } - - setConnectionAnchorRef = (anchorElement: HTMLDivElement) => { - this.connectionAnchorDiv = anchorElement; - }; - - setConnectionSVGRef = (connectionSVG: SVGSVGElement) => { - this.connectionSVG = connectionSVG; - }; - - setConnectionLineRef = (connectionLine: SVGLineElement) => { - this.connectionLine = connectionLine; - }; - - // Recursively find the first parent that is a canvas element - findElementTarget = (element: Element): ElementState | undefined => { - let elementTarget = undefined; - - // Cap recursion at the scene level - if (element === this.scene.div) { - return undefined; - } - - elementTarget = this.scene.findElementByTarget(element); - - if (!elementTarget && element.parentElement) { - elementTarget = this.findElementTarget(element.parentElement); - } - - return elementTarget; - }; - - handleMouseEnter = (event: React.MouseEvent) => { - if (!(event.target instanceof Element) || !this.scene.isEditingEnabled) { - return; - } - - let element: ElementState | undefined = this.findElementTarget(event.target); - - if (!element) { - console.log('no element'); - return; - } - - if (this.isDrawingConnection) { - this.connectionTarget = element; - } else { - this.connectionSource = element; - if (!this.connectionSource) { - console.log('no connection source'); - return; - } - } - - const elementBoundingRect = element.div!.getBoundingClientRect(); - const parentBoundingRect = this.scene.div?.getBoundingClientRect(); - - const relativeTop = elementBoundingRect.top - (parentBoundingRect?.top ?? 0); - const relativeLeft = elementBoundingRect.left - (parentBoundingRect?.left ?? 0); - - if (this.connectionAnchorDiv) { - this.connectionAnchorDiv.style.display = 'none'; - this.connectionAnchorDiv.style.display = 'block'; - this.connectionAnchorDiv.style.top = `${relativeTop}px`; - this.connectionAnchorDiv.style.left = `${relativeLeft}px`; - this.connectionAnchorDiv.style.height = `${elementBoundingRect.height}px`; - this.connectionAnchorDiv.style.width = `${elementBoundingRect.width}px`; - } - }; - - // Return boolean indicates if connection anchors were hidden or not - handleMouseLeave = (event: React.MouseEvent | React.FocusEvent): boolean => { - // If mouse is leaving INTO the anchor image, don't remove div - if ( - event.relatedTarget instanceof HTMLImageElement && - event.relatedTarget.getAttribute('alt') === CONNECTION_ANCHOR_ALT - ) { - return false; - } - - this.connectionTarget = undefined; - this.connectionAnchorDiv!.style.display = 'none'; - return true; - }; - - connectionListener = (event: MouseEvent) => { - event.preventDefault(); - - if (!(this.connectionLine && this.scene.div && this.scene.div.parentElement)) { - return; - } - - const parentBoundingRect = this.scene.div.parentElement.getBoundingClientRect(); - const x = event.pageX - parentBoundingRect.x; - const y = event.pageY - parentBoundingRect.y; - - this.connectionLine.setAttribute('x2', `${x}`); - this.connectionLine.setAttribute('y2', `${y}`); - - const connectionLineX1 = this.connectionLine.x1.baseVal.value; - const connectionLineY1 = this.connectionLine.y1.baseVal.value; - if (!this.didConnectionLeaveHighlight) { - const connectionLength = Math.hypot(x - connectionLineX1, y - connectionLineY1); - if (connectionLength > CONNECTION_ANCHOR_HIGHLIGHT_OFFSET && this.connectionSVG) { - this.didConnectionLeaveHighlight = true; - this.connectionSVG.style.display = 'block'; - this.isDrawingConnection = true; - } - } - - if (!event.buttons) { - if (this.connectionSource && this.connectionSource.div && this.connectionSource.div.parentElement) { - const sourceRect = this.connectionSource.div.getBoundingClientRect(); - const parentRect = this.connectionSource.div.parentElement.getBoundingClientRect(); - - const sourceVerticalCenter = sourceRect.top - parentRect.top + sourceRect.height / 2; - const sourceHorizontalCenter = sourceRect.left - parentRect.left + sourceRect.width / 2; - - // Convert from DOM coords to connection coords - // TODO: Break this out into util function and add tests - const sourceX = (connectionLineX1 - sourceHorizontalCenter) / (sourceRect.width / 2); - const sourceY = (sourceVerticalCenter - connectionLineY1) / (sourceRect.height / 2); - - let targetX; - let targetY; - let targetName; - - if (this.connectionTarget && this.connectionTarget.div) { - const targetRect = this.connectionTarget.div.getBoundingClientRect(); - - const targetVerticalCenter = targetRect.top - parentRect.top + targetRect.height / 2; - const targetHorizontalCenter = targetRect.left - parentRect.left + targetRect.width / 2; - - targetX = (x - targetHorizontalCenter) / (targetRect.width / 2); - targetY = (targetVerticalCenter - y) / (targetRect.height / 2); - targetName = this.connectionTarget.options.name; - } else { - const parentVerticalCenter = parentRect.height / 2; - const parentHorizontalCenter = parentRect.width / 2; - - targetX = (x - parentHorizontalCenter) / (parentRect.width / 2); - targetY = (parentVerticalCenter - y) / (parentRect.height / 2); - } - - const connection = { - source: { - x: sourceX, - y: sourceY, - }, - target: { - x: targetX, - y: targetY, - }, - targetName: targetName, - color: 'white', - size: 10, - path: ConnectionPath.Straight, - }; - - const { options } = this.connectionSource; - if (!options.connections) { - options.connections = []; - } - if (this.didConnectionLeaveHighlight) { - // @ts-ignore - this.connectionSource.options.connections = [...options.connections, connection]; - this.connectionSource.onChange(this.connectionSource.options); - } - } - - if (this.connectionSVG) { - this.connectionSVG.style.display = 'none'; - } - - if (this.scene.selecto && this.scene.selecto.rootContainer) { - this.scene.selecto.rootContainer.style.cursor = 'default'; - this.scene.selecto.rootContainer.removeEventListener('mousemove', this.connectionListener); - } - - this.isDrawingConnection = false; - } - }; - - handleConnectionDragStart = (selectedTarget: HTMLElement, clientX: number, clientY: number) => { - this.scene.selecto!.rootContainer!.style.cursor = 'crosshair'; - if (this.connectionSVG && this.connectionLine && this.scene.div && this.scene.div.parentElement) { - const connectionStartTargetBox = selectedTarget.getBoundingClientRect(); - const parentBoundingRect = this.scene.div.parentElement.getBoundingClientRect(); - - const x = connectionStartTargetBox.x - parentBoundingRect.x + CONNECTION_ANCHOR_HIGHLIGHT_OFFSET; - const y = connectionStartTargetBox.y - parentBoundingRect.y + CONNECTION_ANCHOR_HIGHLIGHT_OFFSET; - - const mouseX = clientX - parentBoundingRect.x; - const mouseY = clientY - parentBoundingRect.y; - - this.connectionLine.setAttribute('x1', `${x}`); - this.connectionLine.setAttribute('y1', `${y}`); - this.connectionLine.setAttribute('x2', `${mouseX}`); - this.connectionLine.setAttribute('y2', `${mouseY}`); - this.didConnectionLeaveHighlight = false; - } - - this.scene.selecto?.rootContainer?.addEventListener('mousemove', this.connectionListener); - }; - - // used for moveable actions - connectionsNeedUpdate = (element: ElementState): boolean => { - return isConnectionSource(element) || isConnectionTarget(element, this.scene.byName); - }; - - render() { - return ( - <> - - - - ); - } -} diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index 034c9e2dab632..6697ec42208f2 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -1,11 +1,6 @@ -import { - configureStore as reduxConfigureStore, - EnhancedStore, - MiddlewareArray, - PreloadedState, -} from '@reduxjs/toolkit'; -import { AnyAction, CombinedState } from 'redux'; -import { ThunkMiddleware } from 'redux-thunk'; +import { configureStore as reduxConfigureStore, createListenerMiddleware } from '@reduxjs/toolkit'; +import { setupListeners } from '@reduxjs/toolkit/query'; +import { Middleware } from 'redux'; import { browseDashboardsAPI } from 'app/features/browse-dashboards/api/browseDashboardsAPI'; import { publicDashboardApi } from 'app/features/dashboard/api/publicDashboardApi'; @@ -20,12 +15,6 @@ import { queryLibraryApi } from '../features/query-library/api/factory'; import { setStore } from './store'; -export type ConfiguredStore = EnhancedStore< - CombinedState, - AnyAction, - MiddlewareArray<[ThunkMiddleware, AnyAction>]> ->; - export function addRootReducer(reducers: any) { // this is ok now because we add reducers before configureStore is called // in the future if we want to add reducers during runtime @@ -33,7 +22,14 @@ export function addRootReducer(reducers: any) { addReducer(reducers); } -export function configureStore>>(initialState?: I | Promise) { +const listenerMiddleware = createListenerMiddleware(); +const extraMiddleware: Middleware[] = []; + +export function addExtraMiddleware(middleware: Middleware) { + extraMiddleware.push(middleware); +} + +export function configureStore(initialState?: Partial) { const store = reduxConfigureStore({ reducer: createRootReducer(), middleware: (getDefaultMiddleware) => diff --git a/public/app/types/window.d.ts b/public/app/types/window.d.ts index 18a6cd977b65a..a82a18a3b17f8 100644 --- a/public/app/types/window.d.ts +++ b/public/app/types/window.d.ts @@ -8,5 +8,11 @@ export declare global { nonce: string | undefined; __POWERED_BY_QIANKUN__: boolean; __INJECTED_PUBLIC_PATH_BY_QIANKUN__: string; + System: typeof System; + } + + // Augment DOMParser to accept TrustedType sanitised content + interface DOMParser { + parseFromString(string: string | TrustedType, type: DOMParserSupportedType): Document; } } diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index 90b98aa760463..8e51e68e558a0 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -1,101 +1,25 @@ -Html Webpack Plugin: -
-  Error: Child compilation failed:
-  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
-  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
-  
-  - Compilation.js:2094 
-    [grafana]/[webpack]/lib/Compilation.js:2094:28
-  
-  - NormalModuleFactory.js:895 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
-  
-  
-  - NormalModuleFactory.js:332 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
-  
-  
-  - NormalModuleFactory.js:509 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
-  
-  - NormalModuleFactory.js:151 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
-  
-  - NormalModuleFactory.js:767 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
-  
-  - NormalModuleFactory.js:979 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
-  
-  - NormalModuleFactory.js:1109 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
-  
-  - Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  
-  - ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  
-  - Compilation.js:2094 
-    [grafana]/[webpack]/lib/Compilation.js:2094:28
-  
-  - NormalModuleFactory.js:895 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
-  
-  
-  - NormalModuleFactory.js:332 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
-  
-  
-  - NormalModuleFactory.js:509 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
-  
-  - NormalModuleFactory.js:151 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
-  
-  - NormalModuleFactory.js:767 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
-  
-  - NormalModuleFactory.js:979 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
-  
-  - NormalModuleFactory.js:1109 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
-  
-  - child-compiler.js:174 
-    [grafana]/[html-webpack-plugin]/lib/child-compiler.js:174:18
-  
-  - Compiler.js:605 finalCallback
-    [grafana]/[webpack]/lib/Compiler.js:605:5
-  
-  - Compiler.js:640 
-    [grafana]/[webpack]/lib/Compiler.js:640:11
-  
-  - Compiler.js:1329 
-    [grafana]/[webpack]/lib/Compiler.js:1329:17
-  
-  
-  - task_queues:95 process.processTicksAndRejections
-    node:internal/process/task_queues:95:5
-  
-
\ No newline at end of file + + + + CodeRabbit Micro-frontend + + + + +
+ + + + + + + + + diff --git a/public/views/error-template.html b/public/views/error-template.html new file mode 100644 index 0000000000000..1eb195cd125b9 --- /dev/null +++ b/public/views/error-template.html @@ -0,0 +1,60 @@ + + + + + + + + + [[.AppTitle]] - Error + + + + [[ if eq .ThemeType "light" ]] + + [[ else ]] + + [[ end ]] + + + + + + +
+
+ +
+
+
+
+
+
[[.Title]]
+
+
+
+ [[if .ErrorMsg]] +

Error details

+
+
[[.ErrorMsg]]
+
+ [[end]] +
+

Check the Grafana server logs for the detailed error message.

+
+
+
+ + diff --git a/public/views/error.html b/public/views/error.html index 90b98aa760463..1eb195cd125b9 100644 --- a/public/views/error.html +++ b/public/views/error.html @@ -1,101 +1,60 @@ -Html Webpack Plugin: -
-  Error: Child compilation failed:
-  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
-  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
-  
-  - Compilation.js:2094 
-    [grafana]/[webpack]/lib/Compilation.js:2094:28
-  
-  - NormalModuleFactory.js:895 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
-  
-  
-  - NormalModuleFactory.js:332 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
-  
-  
-  - NormalModuleFactory.js:509 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
-  
-  - NormalModuleFactory.js:151 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
-  
-  - NormalModuleFactory.js:767 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
-  
-  - NormalModuleFactory.js:979 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
-  
-  - NormalModuleFactory.js:1109 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
-  
-  - Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  
-  - ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  
-  - Compilation.js:2094 
-    [grafana]/[webpack]/lib/Compilation.js:2094:28
-  
-  - NormalModuleFactory.js:895 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
-  
-  
-  - NormalModuleFactory.js:332 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
-  
-  
-  - NormalModuleFactory.js:509 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
-  
-  - NormalModuleFactory.js:151 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
-  
-  - NormalModuleFactory.js:767 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
-  
-  - NormalModuleFactory.js:979 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
-  
-  - NormalModuleFactory.js:1109 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
-  
-  - child-compiler.js:174 
-    [grafana]/[html-webpack-plugin]/lib/child-compiler.js:174:18
-  
-  - Compiler.js:605 finalCallback
-    [grafana]/[webpack]/lib/Compiler.js:605:5
-  
-  - Compiler.js:640 
-    [grafana]/[webpack]/lib/Compiler.js:640:11
-  
-  - Compiler.js:1329 
-    [grafana]/[webpack]/lib/Compiler.js:1329:17
-  
-  
-  - task_queues:95 process.processTicksAndRejections
-    node:internal/process/task_queues:95:5
-  
-
\ No newline at end of file + + + + + + + + + [[.AppTitle]] - Error + + + + [[ if eq .ThemeType "light" ]] + + [[ else ]] + + [[ end ]] + + + + + + +
+
+ +
+
+
+
+
+
[[.Title]]
+
+
+
+ [[if .ErrorMsg]] +

Error details

+
+
[[.ErrorMsg]]
+
+ [[end]] +
+

Check the Grafana server logs for the detailed error message.

+
+
+
+ + diff --git a/public/views/index-microfrontend-template.html b/public/views/index-microfrontend-template.html index edc4c0e7ff2f8..a59112abe3a3d 100644 --- a/public/views/index-microfrontend-template.html +++ b/public/views/index-microfrontend-template.html @@ -7,14 +7,14 @@
- + <% for (index in htmlWebpackPlugin.files.js) { %> <% if (htmlWebpackPlugin.files.jsIntegrity) { %> + + + + + + + + + + +
+
+
+ +
+
+
+

+ If you're seeing this Grafana has failed to load its application files +
+
+

+

+ 1. This could be caused by your reverse proxy settings.

+ 2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath. If not + using a reverse proxy make sure to set serve_from_sub_path to true.
+
+ 3. If you have a local dev build make sure you build frontend using: yarn start, or yarn build
+
+ 4. Sometimes restarting grafana-server can help
+
+ 5. Check if you are using a non-supported browser. For more information, refer to the list of + + supported browsers. +

+
+ +
+ +
+ + + + [[if .GoogleTagManagerId]] + + + + + + [[end]] + + [[range $asset := .Assets.JSFiles]] + + [[end]] + + + + diff --git a/public/views/index.html b/public/views/index.html index 90b98aa760463..3bf6889f52070 100644 --- a/public/views/index.html +++ b/public/views/index.html @@ -1,101 +1,341 @@ -Html Webpack Plugin: -
-  Error: Child compilation failed:
-  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/error-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
-  Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/Compilation.js:2094:28
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:895:13
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :10:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:332:22
-      at eval (eval at create (/home/gurinder/Work/coderabbitai/grafana/node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:509:22
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:151:11
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:767:25
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:979:8
-      at /home/gurinder/Work/coderabbitai/grafana/node_modules/webpack/lib/NormalModuleFactory.js:1109:5
-  
-  - Compilation.js:2094 
-    [grafana]/[webpack]/lib/Compilation.js:2094:28
-  
-  - NormalModuleFactory.js:895 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
-  
-  
-  - NormalModuleFactory.js:332 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
-  
-  
-  - NormalModuleFactory.js:509 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
-  
-  - NormalModuleFactory.js:151 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
-  
-  - NormalModuleFactory.js:767 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
-  
-  - NormalModuleFactory.js:979 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
-  
-  - NormalModuleFactory.js:1109 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
-  
-  - Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  
-  - ModuleNotFoundError: Module not found: Error: Can't resolve '/home/gurinder/Work/coderabbitai/grafana/public/views/index-template.html' in '/home/gurinder/Work/coderabbitai/grafana'
-  
-  - Compilation.js:2094 
-    [grafana]/[webpack]/lib/Compilation.js:2094:28
-  
-  - NormalModuleFactory.js:895 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:895:13
-  
-  
-  - NormalModuleFactory.js:332 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:332:22
-  
-  
-  - NormalModuleFactory.js:509 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:509:22
-  
-  - NormalModuleFactory.js:151 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:151:11
-  
-  - NormalModuleFactory.js:767 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:767:25
-  
-  - NormalModuleFactory.js:979 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:979:8
-  
-  - NormalModuleFactory.js:1109 
-    [grafana]/[webpack]/lib/NormalModuleFactory.js:1109:5
-  
-  - child-compiler.js:174 
-    [grafana]/[html-webpack-plugin]/lib/child-compiler.js:174:18
-  
-  - Compiler.js:605 finalCallback
-    [grafana]/[webpack]/lib/Compiler.js:605:5
-  
-  - Compiler.js:640 
-    [grafana]/[webpack]/lib/Compiler.js:640:11
-  
-  - Compiler.js:1329 
-    [grafana]/[webpack]/lib/Compiler.js:1329:17
-  
-  
-  - task_queues:95 process.processTicksAndRejections
-    node:internal/process/task_queues:95:5
-  
-
\ No newline at end of file + + + + [[ if and .CSPEnabled .IsDevelopmentEnv ]] + + + [[ end ]] + + + + + + [[.AppTitle]] + + + + + + + + + [[ if eq .ThemeType "light" ]] + + [[ else if eq .ThemeType "dark" ]] + + [[ end ]] + + + + + + + + + + + + +
+
+
+ +
+
+
+

+ If you're seeing this Grafana has failed to load its application files +
+
+

+

+ 1. This could be caused by your reverse proxy settings.

+ 2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath. If not + using a reverse proxy make sure to set serve_from_sub_path to true.
+
+ 3. If you have a local dev build make sure you build frontend using: yarn start, or yarn build
+
+ 4. Sometimes restarting grafana-server can help
+
+ 5. Check if you are using a non-supported browser. For more information, refer to the list of + + supported browsers. +

+
+ +
+ +
+ + + + [[if .GoogleTagManagerId]] + + + + + + [[end]] + + [[range $asset := .Assets.JSFiles]] + + [[end]] + + + + diff --git a/scripts/webpack/plugins/HTMLWebpackCSSChunks.js b/scripts/webpack/plugins/HTMLWebpackCSSChunks.js new file mode 100644 index 0000000000000..434d350f71823 --- /dev/null +++ b/scripts/webpack/plugins/HTMLWebpackCSSChunks.js @@ -0,0 +1,42 @@ +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +/* + * This plugin returns the css associated with entrypoints. Those chunks can be found + * in `htmlWebpackPlugin.files.cssChunks`. + * The HTML Webpack plugin removed the chunks object in v5 in favour of an array however if we want + * to do anything smart with hashing (e.g. [contenthash]) we need a map of { themeName: chunkNameWithHash }. + */ +class HTMLWebpackCSSChunks { + /** + * @param {import('webpack').Compiler} compiler + */ + apply(compiler) { + compiler.hooks.compilation.tap( + 'HTMLWebpackCSSChunks', + /** + * @param {import('webpack').Compilation} compilation + */ + (compilation) => { + HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync( + 'HTMLWebpackCSSChunks', + (data, cb) => { + data.assets.cssChunks = {}; + + for (const entryPoint of compilation.entrypoints.values()) { + for (const chunk of entryPoint.chunks) { + const cssFile = [...chunk.files].find((file) => file.endsWith('.css')); + if (cssFile !== undefined) { + data.assets.cssChunks[chunk.name] = cssFile; + } + } + } + + cb(null, data); + } + ); + } + ); + } +} + +module.exports = HTMLWebpackCSSChunks; diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 64243e6a60f01..5f65e9dcee56f 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -1,5 +1,5 @@ 'use strict'; -const { getPackagesSync } = require('@manypkg/get-packages'); + const browserslist = require('browserslist'); const { resolveToEsbuildTarget } = require('esbuild-plugin-browserslist'); const ESLintPlugin = require('eslint-webpack-plugin'); @@ -7,12 +7,10 @@ const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); -const { DefinePlugin, EnvironmentPlugin } = require('webpack'); -const WebpackAssetsManifest = require('webpack-assets-manifest'); +const { DefinePlugin } = require('webpack'); const { merge } = require('webpack-merge'); -const WebpackBar = require('webpackbar'); -const getEnvConfig = require('./env-util.js'); +const HTMLWebpackCSSChunks = require('./plugins/HTMLWebpackCSSChunks'); const common = require('./webpack.common.js'); const esbuildTargets = resolveToEsbuildTarget(browserslist(), { printUnknownTargets: false }); // esbuild-loader 3.0.0+ requires format to be set to prevent it @@ -20,20 +18,11 @@ const esbuildTargets = resolveToEsbuildTarget(browserslist(), { printUnknownTarg const esbuildOptions = { target: esbuildTargets, format: undefined, - jsx: 'automatic', }; -// To speed up webpack and prevent unnecessary rebuilds we ignore decoupled packages -function getDecoupledPlugins() { - const { packages } = getPackagesSync(process.cwd()); - return packages.filter((pkg) => pkg.dir.includes('plugins/datasource')).map((pkg) => `${pkg.dir}/**`); -} - -const envConfig = getEnvConfig(); - module.exports = (env = {}) => { return merge(common, { - devtool: 'source-map', + devtool: 'eval-source-map', mode: 'development', entry: { @@ -45,23 +34,7 @@ module.exports = (env = {}) => { // If we enabled watch option via CLI watchOptions: { - ignored: ['/node_modules/', ...getDecoupledPlugins()], - }, - - resolve: { - alias: { - // Packages linked for development need react to be resolved from the same location - react: path.resolve('./node_modules/react'), - - // Also Grafana packages need to be resolved from the same location so they share - // the same singletons - '@grafana/runtime': path.resolve(__dirname, '../../packages/grafana-runtime'), - '@grafana/data': path.resolve(__dirname, '../../packages/grafana-data'), - - // This is required to correctly resolve react-router-dom when linking with - // local version of @grafana/scenes - 'react-router-dom': path.resolve('./node_modules/react-router-dom'), - }, + ignored: /node_modules/, }, module: { @@ -69,6 +42,7 @@ module.exports = (env = {}) => { rules: [ { test: /\.tsx?$/, + exclude: /node_modules/, use: { loader: 'esbuild-loader', options: esbuildOptions, @@ -81,8 +55,6 @@ module.exports = (env = {}) => { ], }, - // infrastructureLogging: { level: 'error' }, - // https://webpack.js.org/guides/build-performance/#output-without-path-info output: { pathinfo: false, @@ -120,13 +92,11 @@ module.exports = (env = {}) => { }, }, }), - parseInt(env.noLint, 10) - ? new DefinePlugin({}) // bogus plugin to satisfy webpack API - : new ESLintPlugin({ - cache: true, - lintDirtyModulesOnly: true, // don't lint on start, only lint changed files - extensions: ['.ts', '.tsx'], - }), + new ESLintPlugin({ + cache: true, + lintDirtyModulesOnly: true, // don't lint on start, only lint changed files + extensions: ['.ts', '.tsx'], + }), new MiniCssExtractPlugin({ filename: 'grafana.[name].[contenthash].css', }), @@ -151,23 +121,13 @@ module.exports = (env = {}) => { chunksSortMode: 'none', excludeChunks: ['dark', 'light', 'app'], }), + new HTMLWebpackCSSChunks(), new DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development'), + SHOULD_LOG: JSON.stringify('true'), }, }), - new WebpackAssetsManifest({ - entrypoints: true, - integrity: true, - publicPath: true, - }), - new WebpackBar({ - color: '#eb7b18', - name: 'Grafana', - }), - new EnvironmentPlugin(envConfig), ], - - stats: 'minimal', }); }; diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index c160649a82a0e..435570784b911 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -11,7 +11,7 @@ const { DefinePlugin } = require('webpack'); const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); const { merge } = require('webpack-merge'); -const getEnvConfig = require('./env-util.js'); +const HTMLWebpackCSSChunks = require('./plugins/HTMLWebpackCSSChunks'); const common = require('./webpack.common.js'); const esbuildTargets = resolveToEsbuildTarget(browserslist(), { printUnknownTargets: false }); @@ -20,11 +20,8 @@ const esbuildTargets = resolveToEsbuildTarget(browserslist(), { printUnknownTarg const esbuildOptions = { target: esbuildTargets, format: undefined, - jsx: 'automatic', }; -const envConfig = getEnvConfig(); - module.exports = (env = {}) => merge(common, { mode: 'production', @@ -42,6 +39,7 @@ module.exports = (env = {}) => rules: [ { test: /\.tsx?$/, + exclude: /node_modules/, use: { loader: 'esbuild-loader', options: esbuildOptions, @@ -94,6 +92,7 @@ module.exports = (env = {}) => chunksSortMode: 'none', excludeChunks: ['dark', 'light', 'app'], }), + new HTMLWebpackCSSChunks(), new DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development'), @@ -112,6 +111,5 @@ module.exports = (env = {}) => } }); }, - new EnvironmentPlugin(envConfig), ], }); diff --git a/yarn.lock b/yarn.lock index 6fc858dc4301b..c6a9b26b20b1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1561,7 +1561,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:7.25.4, @babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.14.0, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.1, @babel/runtime@npm:^7.24.5, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:7.25.4, @babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.14.0, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.1, @babel/runtime@npm:^7.24.5, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.25.4 resolution: "@babel/runtime@npm:7.25.4" dependencies: @@ -1954,6 +1954,25 @@ __metadata: languageName: node linkType: hard +"@emotion/babel-plugin@npm:^11.12.0": + version: 11.12.0 + resolution: "@emotion/babel-plugin@npm:11.12.0" + dependencies: + "@babel/helper-module-imports": "npm:^7.16.7" + "@babel/runtime": "npm:^7.18.3" + "@emotion/hash": "npm:^0.9.2" + "@emotion/memoize": "npm:^0.9.0" + "@emotion/serialize": "npm:^1.2.0" + babel-plugin-macros: "npm:^3.1.0" + convert-source-map: "npm:^1.5.0" + escape-string-regexp: "npm:^4.0.0" + find-root: "npm:^1.1.0" + source-map: "npm:^0.5.7" + stylis: "npm:4.2.0" + checksum: 10/fe6f4522ea2b61ef4214dd0b0f3778aad9c18434b47e50ae5091af226526bf305455c313065826a090682520c9462c151d4df62ec128f14671d3125afc05b148 + languageName: node + linkType: hard + "@emotion/cache@npm:^10.0.27": version: 10.0.29 resolution: "@emotion/cache@npm:10.0.29" @@ -1979,6 +1998,19 @@ __metadata: languageName: node linkType: hard +"@emotion/cache@npm:^11.13.0, @emotion/cache@npm:^11.13.1": + version: 11.13.1 + resolution: "@emotion/cache@npm:11.13.1" + dependencies: + "@emotion/memoize": "npm:^0.9.0" + "@emotion/sheet": "npm:^1.4.0" + "@emotion/utils": "npm:^1.4.0" + "@emotion/weak-memoize": "npm:^0.4.0" + stylis: "npm:4.2.0" + checksum: 10/090c8ad2e5b23f1b3a95e94f1f0554a40ed1dcd844c9d31629a68ff824eff40f32d1362f67aefa440ee0aabd5a8cabcc76870fd6d77144d3ff251bdcdf1420b9 + languageName: node + linkType: hard + "@emotion/css@npm:11.11.2": version: 11.11.2 resolution: "@emotion/css@npm:11.11.2" @@ -2015,6 +2047,13 @@ __metadata: languageName: node linkType: hard +"@emotion/hash@npm:^0.9.2": + version: 0.9.2 + resolution: "@emotion/hash@npm:0.9.2" + checksum: 10/379bde2830ccb0328c2617ec009642321c0e009a46aa383dfbe75b679c6aea977ca698c832d225a893901f29d7b3eef0e38cf341f560f6b2b56f1ff23c172387 + languageName: node + linkType: hard + "@emotion/is-prop-valid@npm:^1.2.0": version: 1.2.1 resolution: "@emotion/is-prop-valid@npm:1.2.1" @@ -2024,6 +2063,15 @@ __metadata: languageName: node linkType: hard +"@emotion/is-prop-valid@npm:^1.3.0": + version: 1.3.0 + resolution: "@emotion/is-prop-valid@npm:1.3.0" + dependencies: + "@emotion/memoize": "npm:^0.9.0" + checksum: 10/9b395dd9734fa88e24aa5adeef90ba86564d29c85d07a18cd39fbd06fbe597a5008a335a6147088de9f0533dbb3691786c8e10e6eaab5c7d960634833a054005 + languageName: node + linkType: hard + "@emotion/memoize@npm:0.7.4": version: 0.7.4 resolution: "@emotion/memoize@npm:0.7.4" @@ -2038,6 +2086,13 @@ __metadata: languageName: node linkType: hard +"@emotion/memoize@npm:^0.9.0": + version: 0.9.0 + resolution: "@emotion/memoize@npm:0.9.0" + checksum: 10/038132359397348e378c593a773b1148cd0cf0a2285ffd067a0f63447b945f5278860d9de718f906a74c7c940ba1783ac2ca18f1c06a307b01cc0e3944e783b1 + languageName: node + linkType: hard + "@emotion/react@npm:11.11.4, @emotion/react@npm:^11.8.1": version: 11.11.4 resolution: "@emotion/react@npm:11.11.4" @@ -2059,6 +2114,27 @@ __metadata: languageName: node linkType: hard +"@emotion/react@npm:^11.13.3": + version: 11.13.3 + resolution: "@emotion/react@npm:11.13.3" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.12.0" + "@emotion/cache": "npm:^11.13.0" + "@emotion/serialize": "npm:^1.3.1" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0" + "@emotion/utils": "npm:^1.4.0" + "@emotion/weak-memoize": "npm:^0.4.0" + hoist-non-react-statics: "npm:^3.3.1" + peerDependencies: + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/ee70d3afc2e8dd771e6fe176d27dd87a5e21a54e54d871438fd1caa5aa2312d848c6866292fdc65a6ea1c945147c8422bda2d22ed739178af9902dc86d6b298a + languageName: node + linkType: hard + "@emotion/serialize@npm:^0.11.15, @emotion/serialize@npm:^0.11.16": version: 0.11.16 resolution: "@emotion/serialize@npm:0.11.16" @@ -2085,6 +2161,19 @@ __metadata: languageName: node linkType: hard +"@emotion/serialize@npm:^1.2.0, @emotion/serialize@npm:^1.3.0, @emotion/serialize@npm:^1.3.1": + version: 1.3.1 + resolution: "@emotion/serialize@npm:1.3.1" + dependencies: + "@emotion/hash": "npm:^0.9.2" + "@emotion/memoize": "npm:^0.9.0" + "@emotion/unitless": "npm:^0.10.0" + "@emotion/utils": "npm:^1.4.0" + csstype: "npm:^3.0.2" + checksum: 10/4bbb9b417f88a7bb55c4ffba101e3e53059029c0258969683bb11216906e08cbd687b5674ec787ec41e5340399fb08af8881d6cf913caf8a5fdf84c4f4890f33 + languageName: node + linkType: hard + "@emotion/sheet@npm:0.9.4": version: 0.9.4 resolution: "@emotion/sheet@npm:0.9.4" @@ -2099,6 +2188,33 @@ __metadata: languageName: node linkType: hard +"@emotion/sheet@npm:^1.4.0": + version: 1.4.0 + resolution: "@emotion/sheet@npm:1.4.0" + checksum: 10/8ac6e9bf6b373a648f26ae7f1c24041038524f4c72f436f4f8c4761c665e58880c3229d8d89b1f7a4815dd8e5b49634d03e60187cb6f93097d7f7c1859e869d5 + languageName: node + linkType: hard + +"@emotion/styled@npm:^11.13.0": + version: 11.13.0 + resolution: "@emotion/styled@npm:11.13.0" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.12.0" + "@emotion/is-prop-valid": "npm:^1.3.0" + "@emotion/serialize": "npm:^1.3.0" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0" + "@emotion/utils": "npm:^1.4.0" + peerDependencies: + "@emotion/react": ^11.0.0-rc.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/5463a0f15fc12a9e20340f52df49461e948c3ae7e2dd763db0ff937b0b96dd4e82eed85cd15e24621efb3b097a095b88b01d60f50cf6f38fe3ab7db6e77f9615 + languageName: node + linkType: hard + "@emotion/stylis@npm:0.8.5": version: 0.8.5 resolution: "@emotion/stylis@npm:0.8.5" @@ -2113,6 +2229,13 @@ __metadata: languageName: node linkType: hard +"@emotion/unitless@npm:^0.10.0": + version: 0.10.0 + resolution: "@emotion/unitless@npm:0.10.0" + checksum: 10/6851c16edce01c494305f43b2cad7a26b939a821131b7c354e49b8e3b012c8810024755b0f4a03ef51117750309e55339825a97bd10411fb3687e68904769106 + languageName: node + linkType: hard + "@emotion/unitless@npm:^0.8.1": version: 0.8.1 resolution: "@emotion/unitless@npm:0.8.1" @@ -2129,6 +2252,15 @@ __metadata: languageName: node linkType: hard +"@emotion/use-insertion-effect-with-fallbacks@npm:^1.1.0": + version: 1.1.0 + resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.1.0" + peerDependencies: + react: ">=16.8.0" + checksum: 10/33a10f44a873b3f5ccd2a1a3d13c2f34ed628f5a2be1ccf28540a86535a14d3a930afcbef209d48346a22ec60ff48f43c86ee9c846b9480d23a55a17145da66c + languageName: node + linkType: hard + "@emotion/utils@npm:0.11.3": version: 0.11.3 resolution: "@emotion/utils@npm:0.11.3" @@ -2143,6 +2275,13 @@ __metadata: languageName: node linkType: hard +"@emotion/utils@npm:^1.4.0": + version: 1.4.0 + resolution: "@emotion/utils@npm:1.4.0" + checksum: 10/e4cdb51819db01fec21c3e35a1391900c9e7f3ac1e7ecb419c8e408464830cd7ef6e1a116381cbfe3fb1039406fb7ed35f16a1575d502c92bc9f81bc13a3ee5a + languageName: node + linkType: hard + "@emotion/weak-memoize@npm:0.2.5": version: 0.2.5 resolution: "@emotion/weak-memoize@npm:0.2.5" @@ -2157,6 +2296,13 @@ __metadata: languageName: node linkType: hard +"@emotion/weak-memoize@npm:^0.4.0": + version: 0.4.0 + resolution: "@emotion/weak-memoize@npm:0.4.0" + checksum: 10/db5da0e89bd752c78b6bd65a1e56231f0abebe2f71c0bd8fc47dff96408f7065b02e214080f99924f6a3bfe7ee15afc48dad999d76df86b39b16e513f7a94f52 + languageName: node + linkType: hard + "@es-joy/jsdoccomment@npm:~0.40.1": version: 0.40.1 resolution: "@es-joy/jsdoccomment@npm:0.40.1" @@ -2793,6 +2939,20 @@ __metadata: languageName: node linkType: hard +"@floating-ui/react@npm:^0.26.2": + version: 0.26.23 + resolution: "@floating-ui/react@npm:0.26.23" + dependencies: + "@floating-ui/react-dom": "npm:^2.1.1" + "@floating-ui/utils": "npm:^0.2.7" + tabbable: "npm:^6.0.0" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10/a2ffeb0bae72cac9e6583d9651e75e94c261a9e78ca4a5e862b7d33f2c19ae014cbe272627a0a0a5a2b526280efab17ec687d32ba02f6ce4e924bec562ae06ab + languageName: node + linkType: hard + "@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.7": version: 0.2.7 resolution: "@floating-ui/utils@npm:0.2.7" @@ -5058,6 +5218,147 @@ __metadata: languageName: node linkType: hard +"@mui/core-downloads-tracker@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/core-downloads-tracker@npm:6.0.0" + checksum: 10/a83a2283e3539cd48269f2febf882fb6a0d42cf3df3460610344d456a6a7839d797d204e4dd2a3a04f38fe1efcc8cc6e7d8e1c54c99c40448b57730669c9939e + languageName: node + linkType: hard + +"@mui/material@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/material@npm:6.0.0" + dependencies: + "@babel/runtime": "npm:^7.25.0" + "@mui/core-downloads-tracker": "npm:^6.0.0" + "@mui/system": "npm:^6.0.0" + "@mui/types": "npm:^7.2.16" + "@mui/utils": "npm:^6.0.0" + "@popperjs/core": "npm:^2.11.8" + "@types/react-transition-group": "npm:^4.4.11" + clsx: "npm:^2.1.1" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.3.1" + react-transition-group: "npm:^4.4.5" + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@mui/material-pigment-css": ^6.0.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@mui/material-pigment-css": + optional: true + "@types/react": + optional: true + checksum: 10/f12c8c62886de330ca9d24fd76cabb11aaf68095dd92c24cef7d7d7c3c45fd074be0b8754da4e822aae3d437fdfd1af38c0b4e574b32bbbdfb211ed28c815c74 + languageName: node + linkType: hard + +"@mui/private-theming@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/private-theming@npm:6.0.0" + dependencies: + "@babel/runtime": "npm:^7.25.0" + "@mui/utils": "npm:^6.0.0" + prop-types: "npm:^15.8.1" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/abbed60063c733a0a7a8ceffe4c31bdf10c9f9e81fb6aba4f284baaf1edd29c87601280d76c6727afc4cc05c5eff1f8331136241454ce2e95a3326a25c0cc36b + languageName: node + linkType: hard + +"@mui/styled-engine@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/styled-engine@npm:6.0.0" + dependencies: + "@babel/runtime": "npm:^7.25.0" + "@emotion/cache": "npm:^11.13.1" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + peerDependencies: + "@emotion/react": ^11.4.1 + "@emotion/styled": ^11.3.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + checksum: 10/3b261526b9a558a42502b441a384a4593ad5defc6564e8020b547b3d187f23df904de904d1c809fd4f094c107868a6a2f8c72796dad30fa8794e4bc55058e1c2 + languageName: node + linkType: hard + +"@mui/system@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/system@npm:6.0.0" + dependencies: + "@babel/runtime": "npm:^7.25.0" + "@mui/private-theming": "npm:^6.0.0" + "@mui/styled-engine": "npm:^6.0.0" + "@mui/types": "npm:^7.2.16" + "@mui/utils": "npm:^6.0.0" + clsx: "npm:^2.1.1" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 10/7ed8fb17beb12242fa46c0d16841e02514d9d8162dc36426e1f3535b1ce296d2eddf3c709e13ef84e3f94c988ba37cc40b9ba54b105b301d2b10cdffbd610a2d + languageName: node + linkType: hard + +"@mui/types@npm:^7.2.16": + version: 7.2.16 + resolution: "@mui/types@npm:7.2.16" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/44652fd7afd0063ed38870810ef0524ee5bf9e8fee4aece8d5b76c89dd3e83f6aa370beacc45c0381546b0917cab9af6671d0f4ba7c55af32bd3051a074a2774 + languageName: node + linkType: hard + +"@mui/utils@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/utils@npm:6.0.0" + dependencies: + "@babel/runtime": "npm:^7.25.0" + "@mui/types": "npm:^7.2.16" + "@types/prop-types": "npm:^15.7.12" + clsx: "npm:^2.1.1" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.3.1" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/e14fdaacdd39bb388b6d0536224a966a057da2040c315c98f992531b44ef470b9e8cc3ae60bb61a03bbf3a8a282e78f342eb297aff5012f15be5eee14f80e883 + languageName: node + linkType: hard + "@ndelangen/get-tarball@npm:^3.0.7": version: 3.0.7 resolution: "@ndelangen/get-tarball@npm:3.0.7" @@ -5996,7 +6297,7 @@ __metadata: languageName: node linkType: hard -"@popperjs/core@npm:2.11.8, @popperjs/core@npm:^2.11.5": +"@popperjs/core@npm:2.11.8, @popperjs/core@npm:^2.11.5, @popperjs/core@npm:^2.11.8": version: 2.11.8 resolution: "@popperjs/core@npm:2.11.8" checksum: 10/ddd16090cde777aaf102940f05d0274602079a95ad9805bd20bc55dcc7c3a2ba1b99dd5c73e5cc2753c3d31250ca52a67d58059459d7d27debb983a9f552936c @@ -10017,6 +10318,13 @@ __metadata: languageName: node linkType: hard +"@types/prop-types@npm:^15.7.12": + version: 15.7.12 + resolution: "@types/prop-types@npm:15.7.12" + checksum: 10/ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe + languageName: node + linkType: hard + "@types/qs@npm:*, @types/qs@npm:^6.9.5": version: 6.9.7 resolution: "@types/qs@npm:6.9.7" @@ -10144,7 +10452,7 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:4.4.11, @types/react-transition-group@npm:^4.4.0": +"@types/react-transition-group@npm:4.4.11, @types/react-transition-group@npm:^4.4.0, @types/react-transition-group@npm:^4.4.11": version: 4.4.11 resolution: "@types/react-transition-group@npm:4.4.11" dependencies: @@ -11336,6 +11644,13 @@ __metadata: languageName: node linkType: hard +"ace-builds@npm:^1.32.8": + version: 1.36.0 + resolution: "ace-builds@npm:1.36.0" + checksum: 10/cbbe61902ddfcf6bdb60de7c14e55beee742eecf66d10133cee1ec1ea4676bb3506d9a812c5610b52c0be7972d7fb691fa108c9d07f0d7cd6718ccbab92fc3b2 + languageName: node + linkType: hard + "acorn-globals@npm:^7.0.0": version: 7.0.1 resolution: "acorn-globals@npm:7.0.1" @@ -13327,6 +13642,13 @@ __metadata: languageName: node linkType: hard +"clsx@npm:^2.1.0, clsx@npm:^2.1.1": + version: 2.1.1 + resolution: "clsx@npm:2.1.1" + checksum: 10/cdfb57fa6c7649bbff98d9028c2f0de2f91c86f551179541cf784b1cfdc1562dcb951955f46d54d930a3879931a980e32a46b598acaea274728dbe068deca919 + languageName: node + linkType: hard + "cmd-shim@npm:6.0.3, cmd-shim@npm:^6.0.0": version: 6.0.3 resolution: "cmd-shim@npm:6.0.3" @@ -14430,7 +14752,7 @@ __metadata: languageName: node linkType: hard -"csstype@npm:3.1.3, csstype@npm:^3.0.2, csstype@npm:^3.1.2": +"csstype@npm:3.1.3, csstype@npm:^3.0.2, csstype@npm:^3.1.2, csstype@npm:^3.1.3": version: 3.1.3 resolution: "csstype@npm:3.1.3" checksum: 10/f593cce41ff5ade23f44e77521e3a1bcc2c64107041e1bf6c3c32adc5187d0d60983292fda326154d20b01079e24931aa5b08e4467cc488b60bb1e7f6d478ade @@ -14947,7 +15269,7 @@ __metadata: languageName: node linkType: hard -"date-fns@npm:3.6.0": +"date-fns@npm:3.6.0, date-fns@npm:^3.3.1": version: 3.6.0 resolution: "date-fns@npm:3.6.0" checksum: 10/cac35c58926a3b5d577082ff2b253612ec1c79eb6754fddef46b6a8e826501ea2cb346ecbd211205f1ba382ddd1f9d8c3f00bf433ad63cc3063454d294e3a6b8 @@ -15353,6 +15675,13 @@ __metadata: languageName: node linkType: hard +"diff-match-patch@npm:^1.0.5": + version: 1.0.5 + resolution: "diff-match-patch@npm:1.0.5" + checksum: 10/fd1ab417eba9559bda752a4dfc9a8ac73fa2ca8b146d29d153964b437168e301c09d8a688fae0cd81d32dc6508a4918a94614213c85df760793f44e245173bb6 + languageName: node + linkType: hard + "diff-sequences@npm:^27.5.1": version: 27.5.1 resolution: "diff-sequences@npm:27.5.1" @@ -18424,7 +18753,8 @@ __metadata: "@cypress/webpack-preprocessor": "npm:6.0.2" "@emotion/css": "npm:11.11.2" "@emotion/eslint-plugin": "npm:11.11.0" - "@emotion/react": "npm:11.11.4" + "@emotion/react": "npm:^11.13.3" + "@emotion/styled": "npm:^11.13.0" "@fingerprintjs/fingerprintjs": "npm:^3.4.2" "@floating-ui/react": "npm:0.26.22" "@formatjs/intl-durationformat": "npm:^0.2.4" @@ -18465,6 +18795,7 @@ __metadata: "@manypkg/get-packages": "npm:^2.2.0" "@msagl/core": "npm:^1.1.19" "@msagl/parser": "npm:^1.1.19" + "@mui/material": "npm:^6.0.0" "@opentelemetry/api": "npm:1.9.0" "@opentelemetry/exporter-collector": "npm:0.25.0" "@opentelemetry/semantic-conventions": "npm:1.25.1" @@ -18676,6 +19007,8 @@ __metadata: rc-tree: "npm:5.8.8" re-resizable: "npm:6.9.17" react: "npm:18.2.0" + react-ace: "npm:^12.0.0" + react-datepicker: "npm:^7.3.0" react-diff-viewer: "npm:^3.1.1" react-dom: "npm:18.2.0" react-draggable: "npm:4.4.6" @@ -22133,6 +22466,13 @@ __metadata: languageName: node linkType: hard +"lodash.isequal@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.isequal@npm:4.5.0" + checksum: 10/82fc58a83a1555f8df34ca9a2cd300995ff94018ac12cc47c349655f0ae1d4d92ba346db4c19bbfc90510764e0c00ddcc985a358bdcd4b3b965abf8f2a48a214 + languageName: node + linkType: hard + "lodash.ismatch@npm:^4.4.0": version: 4.4.0 resolution: "lodash.ismatch@npm:4.4.0" @@ -26695,6 +27035,22 @@ __metadata: languageName: node linkType: hard +"react-ace@npm:^12.0.0": + version: 12.0.0 + resolution: "react-ace@npm:12.0.0" + dependencies: + ace-builds: "npm:^1.32.8" + diff-match-patch: "npm:^1.0.5" + lodash.get: "npm:^4.4.2" + lodash.isequal: "npm:^4.5.0" + prop-types: "npm:^15.8.1" + peerDependencies: + react: ^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10/56bd138183f2ebf95abb5a506a7e1d1a12e5a1e72e3a39312ef0ee5b2fe0148b430d769f0fceb84c63050e31ea6e22681260a46bc7802cd2295d7679f0c51cbc + languageName: node + linkType: hard + "react-beautiful-dnd@npm:^13.1.1": version: 13.1.1 resolution: "react-beautiful-dnd@npm:13.1.1" @@ -26779,6 +27135,22 @@ __metadata: languageName: node linkType: hard +"react-datepicker@npm:^7.3.0": + version: 7.3.0 + resolution: "react-datepicker@npm:7.3.0" + dependencies: + "@floating-ui/react": "npm:^0.26.2" + clsx: "npm:^2.1.0" + date-fns: "npm:^3.3.1" + prop-types: "npm:^15.7.2" + react-onclickoutside: "npm:^6.13.0" + peerDependencies: + react: ^16.9.0 || ^17 || ^18 + react-dom: ^16.9.0 || ^17 || ^18 + checksum: 10/594e23086a9a3e5a84b25c4e96f1f4e379f0702e3407af54045177cb82a7d8f78f09599f5ae227e9cb902e79ebc70cc8b814ea0e500c28eeee9ce6f741039878 + languageName: node + linkType: hard + "react-debounce-input@npm:=3.3.0": version: 3.3.0 resolution: "react-debounce-input@npm:3.3.0" @@ -27089,6 +27461,13 @@ __metadata: languageName: node linkType: hard +"react-is@npm:^18.3.1": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: 10/d5f60c87d285af24b1e1e7eaeb123ec256c3c8bdea7061ab3932e3e14685708221bf234ec50b21e10dd07f008f1b966a2730a0ce4ff67905b3872ff2042aec22 + languageName: node + linkType: hard + "react-lifecycles-compat@npm:^3.0.4": version: 3.0.4 resolution: "react-lifecycles-compat@npm:3.0.4" @@ -27138,6 +27517,16 @@ __metadata: languageName: node linkType: hard +"react-onclickoutside@npm:^6.13.0": + version: 6.13.1 + resolution: "react-onclickoutside@npm:6.13.1" + peerDependencies: + react: ^15.5.x || ^16.x || ^17.x || ^18.x + react-dom: ^15.5.x || ^16.x || ^17.x || ^18.x + checksum: 10/bc1f5813ad25d81602661848b19f0c15357b87e224ddf5abc2ac4502ffddbe7ee44688827b0522327868ae63ab229030d2a2f185007ecfe861f1128d3e5319e6 + languageName: node + linkType: hard + "react-popper-tooltip@npm:^4.4.2": version: 4.4.2 resolution: "react-popper-tooltip@npm:4.4.2" @@ -27530,7 +27919,7 @@ __metadata: languageName: node linkType: hard -"react-transition-group@npm:4.4.5, react-transition-group@npm:^4.3.0": +"react-transition-group@npm:4.4.5, react-transition-group@npm:^4.3.0, react-transition-group@npm:^4.4.5": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5" dependencies: From d1bea195d4c58668a0d15473b2f3318eb5efb7db Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Thu, 29 Aug 2024 14:58:54 -0400 Subject: [PATCH 095/101] webpack changes --- go.mod | 8 +- go.sum | 98 ------------------- go.work.sum | 14 +-- pkg/api/http_server.go | 2 +- pkg/plugins/pfs/corelist/corelist_load_gen.go | 90 ----------------- public/microfrontends/fn_dashboard/index.html | 8 +- public/views/swagger.html | 2 +- scripts/webpack/webpack.dev.js | 18 +++- scripts/webpack/webpack.prod.js | 14 ++- 9 files changed, 46 insertions(+), 208 deletions(-) delete mode 100644 pkg/plugins/pfs/corelist/corelist_load_gen.go diff --git a/go.mod b/go.mod index d7fccf67113ac..cb285d8317112 100644 --- a/go.mod +++ b/go.mod @@ -480,24 +480,18 @@ require ( github.com/grafadruid/go-druid v0.0.7-0.20230607082331-983aa577d90a github.com/grafana/authlib v0.0.0-20240828122726-9edfcbea43e2 github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd - github.com/grafana/thema v0.0.0-20240605110052-2016107581da ) require ( cloud.google.com/go/longrunning v0.5.12 // indirect github.com/at-wat/mqtt-go v0.19.4 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect - github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect - github.com/cockroachdb/redact v1.1.3 // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect - github.com/getsentry/sentry-go v0.12.0 // indirect github.com/grafana/grafana/pkg/semconv v0.0.0-20240808213237-f4d2e064f435 // indirect github.com/hairyhenderson/go-which v0.2.0 // indirect github.com/iancoleman/orderedmap v0.3.0 // indirect - github.com/kr/pretty v0.3.1 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/speakeasy-api/openapi-overlay v0.9.0 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/yudai/pp v2.0.1+incompatible // indirect ) // Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream diff --git a/go.sum b/go.sum index 383cfdd9912dc..1aceb2cbc6d5e 100644 --- a/go.sum +++ b/go.sum @@ -1341,7 +1341,6 @@ filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg= filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= @@ -1424,8 +1423,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/Code-Hex/go-generics-cache v1.5.1 h1:6vhZGc5M7Y/YD8cIUcY8kcuQLB4cHR7U+0KMqAA0KcU= github.com/Code-Hex/go-generics-cache v1.5.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= @@ -1438,7 +1435,6 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/KimMachineGun/automemlimit v0.6.0/go.mod h1:T7xYht7B8r6AG/AqFcUdc7fzd2bIdBKmepfP2S1svPY= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -1472,7 +1468,6 @@ github.com/RoaringBitmap/real-roaring-datasets v0.0.0-20190726190000-eb7c87156f7 github.com/RoaringBitmap/roaring v0.9.1/go.mod h1:h1B7iIUOmnAeb5ytYMvnHJwxMc6LUrwBnzXWRuqTQUc= github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo= github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -1481,7 +1476,6 @@ github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3H 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= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -1604,7 +1598,6 @@ github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f h1:y06x6vGnFYfXUoVMbrcP1Uzpj4JG01eB5vRps9G8agM= github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f/go.mod h1:2stgcRjl6QmW+gU2h5E7BQXg4HU0gzxKWDuT5HviN9s= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= @@ -1738,15 +1731,7 @@ github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b80 github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/containerd/cgroups/v3 v3.0.1/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw= github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -1802,9 +1787,7 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= 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-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= @@ -1849,7 +1832,6 @@ github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/efficientgo/tools/core v0.0.0-20220225185207-fe763185946b h1:ZHiD4/yE4idlbqvAO6iYCOYRzOMRpxkW+FKasRA3tsQ= github.com/efficientgo/tools/core v0.0.0-20220225185207-fe763185946b/go.mod h1:OmVcnJopJL8d3X3sSXTiypGoUSgFq1aDGmlrdi9dn/M= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M= github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= @@ -1885,12 +1867,10 @@ github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87K github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= @@ -1900,7 +1880,6 @@ github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8Wlg github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 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= @@ -1925,21 +1904,13 @@ github.com/fullstorydev/grpchan v1.1.1 h1:heQqIJlAv5Cnks9a70GRL2EJke6QQoUB25VGR6 github.com/fullstorydev/grpchan v1.1.1/go.mod h1:f4HpiV8V6htfY/K44GWV1ESQzHBTq7DinhzqQ95lpgc= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gchaincl/sqlhooks v1.3.0 h1:yKPXxW9a5CjXaVf2HkQn6wn7TZARvbAOAelr3H8vK2Y= github.com/gchaincl/sqlhooks v1.3.0/go.mod h1:9BypXnereMT0+Ys8WGWHqzgkkOfHIhyeUCqXC24ra34= github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= @@ -1982,7 +1953,6 @@ 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.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/analysis v0.21.5/go.mod h1:25YcZosX9Lwz2wBsrFrrsL8bmjjXdlyP6zsr2AMy29M= @@ -2055,11 +2025,8 @@ github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= @@ -2080,11 +2047,9 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -2149,7 +2114,6 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -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= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= @@ -2285,7 +2249,6 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -2361,8 +2324,6 @@ github.com/grafana/sqlds/v3 v3.2.0 h1:WXuYEaFfiCvgm8kK2ixx44/zAEjFzCylA2+RF3GBqZ github.com/grafana/sqlds/v3 v3.2.0/go.mod h1:kH0WuHUR3j0Q7IEymbm2JiaPckUhRCbqjV9ajaBAnmM= github.com/grafana/tempo v1.5.1-0.20240604192202-01f4bc8ac2d1 h1:cSE1u4IUQ9EPcQErMZ9YVYayJTIGgH4g2E1Rp2WmGy0= github.com/grafana/tempo v1.5.1-0.20240604192202-01f4bc8ac2d1/go.mod h1:ttAEYdYVYBNngPulKIHkmHvjXfLfX7jDWI74jzb8jh4= -github.com/grafana/thema v0.0.0-20240605110052-2016107581da h1:QhkXTxftS9baiXXweuMO6+MN4cIDrQxQpT1gEVuIpMk= -github.com/grafana/thema v0.0.0-20240605110052-2016107581da/go.mod h1:AOyC9mxvuzfiGf4GgVu0dLpPlRl8clSnhRNUpOK0NAA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= @@ -2492,7 +2453,6 @@ github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4 github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= @@ -2507,7 +2467,6 @@ github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -2524,11 +2483,6 @@ github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/ionos-cloud/sdk-go/v6 v6.1.11 h1:J/uRN4UWO3wCyGOeDdMKv8LWRzKu6UIkLEaes38Kzh8= github.com/ionos-cloud/sdk-go/v6 v6.1.11/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= @@ -2601,15 +2555,9 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/karlseguin/ccache/v3 v3.0.5 h1:hFX25+fxzNjsRlREYsoGNa2LoVEw5mPF8wkWq/UnevQ= github.com/karlseguin/ccache/v3 v3.0.5/go.mod h1:qxC372+Qn+IBj8Pe3KvGjHPj0sWwEF7AeZVhsNPZ6uY= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -2617,8 +2565,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= @@ -2626,7 +2572,6 @@ github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -2652,8 +2597,6 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= @@ -2699,12 +2642,10 @@ github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxq github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM= github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -2713,9 +2654,7 @@ github.com/mattn/go-ieproxy v0.0.11 h1:MQ/5BuGSgDAHZOJe6YY80IF2UVCfGkwfo6AeD7HtH github.com/mattn/go-ieproxy v0.0.11/go.mod h1:/NsJd+kxZBmjMc5hrJCKMbP57B84rvq9BiDRbtO9AS0= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -2736,16 +2675,13 @@ github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= 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/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/microsoft/go-mssqldb v1.7.0 h1:sgMPW0HA6Ihd37Yx0MzHyKD726C2kY/8KJsQtXHNaAs= github.com/microsoft/go-mssqldb v1.7.0/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -2836,7 +2772,6 @@ github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto= github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= @@ -2890,7 +2825,6 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 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= @@ -2997,8 +2931,6 @@ github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFu github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= -github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -3114,7 +3046,6 @@ github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYe github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= @@ -3144,7 +3075,6 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26 h1:F+GIVtGqCFxPxO46ujf8cEOP574MBoRm3gNbPXECbxs= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/scottlepp/go-duck v0.1.0 h1:Lfunl1wd767v0dF0/dr+mBh+KnUFuDmgNycC76NJjeE= github.com/scottlepp/go-duck v0.1.0/go.mod h1:xGoYUbgph5AbxwsMElWv2i/mgzQl89WIgwE69Ytml7Q= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -3154,7 +3084,6 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/segmentio/encoding v0.3.6 h1:E6lVLyDPseWEulBmCmAKPanDd3jiyGDo5gMcugCRwZQ= github.com/segmentio/encoding v0.3.6/go.mod h1:n0JeuIqEQrQoPDGsjo8UNd1iA0U8d8+oHAA4E3G3OxM= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= @@ -3288,11 +3217,7 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 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.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 h1:aVGB3YnaS/JNfOW3tiHIlmNmTDg618va+eT0mVomgyI= @@ -3308,13 +3233,8 @@ github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vburenin/ifacemaker v1.2.1/go.mod h1:5WqrzX2aD7/hi+okBjcaEQJMg4lDGrpuEX3B8L4Wgrs= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= @@ -3332,9 +3252,6 @@ github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3k github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= @@ -3344,7 +3261,6 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= @@ -3529,7 +3445,6 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -3537,7 +3452,6 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -3661,7 +3575,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -3672,7 +3585,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -3709,7 +3621,6 @@ golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -3842,7 +3753,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -4016,7 +3926,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -4028,14 +3937,12 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -4594,17 +4501,13 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -4623,7 +4526,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.work.sum b/go.work.sum index 5d638e1284a5d..7b76575e97b9e 100644 --- a/go.work.sum +++ b/go.work.sum @@ -654,6 +654,7 @@ github.com/ClickHouse/ch-go v0.58.2/go.mod h1:Ap/0bEmiLa14gYjCiRkYGbXvbe8vwdrfTY github.com/ClickHouse/clickhouse-go/v2 v2.17.1 h1:ZCmAYWpu75IyEi7+Yrs/uaAjiCGY5wfW5kXo64exkX4= github.com/ClickHouse/clickhouse-go/v2 v2.17.1/go.mod h1:rkGTvFDTLqLIm0ma+13xmcCfr/08Gvs7KmFt1tgiWHQ= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0 h1:1PwO5w5VCtlUUl+KTOBsTGZlhjWkcybsGaAau52tOy8= github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= @@ -841,8 +842,6 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= github.com/drone/drone-runtime v1.1.0 h1:IsKbwiLY6+ViNBzX0F8PERJVZZcEJm9rgxEh3uZP5IE= github.com/drone/drone-runtime v1.1.0/go.mod h1:+osgwGADc/nyl40J0fdsf8Z09bgcBZXvXXnLOY48zYs= github.com/drone/drone-yaml v1.2.3 h1:SWzLmzr8ARhbtw1WsVDENa8WFY2Pi9l0FVMfafVUWz8= @@ -871,6 +870,7 @@ github.com/expr-lang/expr v1.16.2 h1:JvMnzUs3LeVHBvGFcXYmXo+Q6DPDmzrlcSBO6Wy3w4s github.com/expr-lang/expr v1.16.2/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 h1:DddqAaWDpywytcG8w/qoQ5sAN8X12d3Z3koB0C3Rxsc= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= @@ -942,6 +942,7 @@ github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198/go.mod h1:DTh/Y2+Nbn github.com/goccy/go-yaml v1.11.0 h1:n7Z+zx8S9f9KgzG6KtQKf+kwqXZlLNR2F6018Dgau54= github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4 h1:vF83LI8tAakwEwvWZtrIEx7pOySacl2TOxx6eXk4ePo= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= @@ -983,7 +984,6 @@ github.com/grafadruid/go-druid v0.0.6 h1:Nt9jQrhrtHi1BJICN9aDJgYDmBmc10pJYpQiuwA github.com/grafadruid/go-druid v0.0.6/go.mod h1:KY3a6MrVMKkXgMTwBS9Nrhm1E8OWyR4gd0WzUi8d/zM= github.com/grafana/authlib v0.0.0-20240730122259-a0d13672efb1/go.mod h1:YA9We4kTafu7mlMnUh3In6Q2wpg8fYN3ycgCKOK1TB8= github.com/grafana/authlib/claims v0.0.0-20240809101159-74eaccc31a06/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= -github.com/grafana/authlib/claims v0.0.0-20240827210201-19d5347dd8dd/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A= github.com/grafana/gomemcache v0.0.0-20240229205252-cd6a66d6fb56/go.mod h1:PGk3RjYHpxMM8HFPhKKo+vve3DdlPUELZLSDEFehPuU= github.com/grafana/grafana-plugin-sdk-go v0.235.0/go.mod h1:6n9LbrjGL3xAATntYVNcIi90G9BVHRJjzHKz5FXVfWw= github.com/grafana/prometheus-alertmanager v0.25.1-0.20240422145632-c33c6b5b6e6b h1:HCbWyVL6vi7gxyO76gQksSPH203oBJ1MJ3JcG1OQlsg= @@ -1283,6 +1283,7 @@ github.com/sagikazarmark/crypt v0.17.0/go.mod h1:SMtHTvdmsZMuY/bpZoqokSoChIrcJ/e github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e h1:uO75wNGioszjmIzcY/tvdDYKRLVvzggtAmmJkn9j4GQ= github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e/go.mod h1:tm/wZFQ8e24NYaBGIlnO2WGCAi67re4HHuOm0sftE/M= github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY= @@ -1292,8 +1293,6 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I github.com/sony/gobreaker v0.4.1 h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/speakeasy-api/openapi-overlay v0.9.0 h1:Wrz6NO02cNlLzx1fB093lBlYxSI54VRhy1aSutx0PQg= -github.com/speakeasy-api/openapi-overlay v0.9.0/go.mod h1:f5FloQrHA7MsxYg9djzMD5h6dxrHjVVByWKh7an8TRc= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= @@ -1337,8 +1336,6 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX8Wdm2/JPA= @@ -1350,8 +1347,11 @@ github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index 9f5ac6b79fd9c..c3742b15dad4c 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -602,7 +602,7 @@ func (hs *HTTPServer) addMiddlewaresAndStaticRoutes() { m.UseMiddleware(hs.Csrf.Middleware()) hs.mapStatic(m, hs.Cfg.StaticRootPath, "build", "public/build") - hs.mapStatic(m, hs.Cfg.StaticRootPath, "", "public", "/public/views/swagger.html") + hs.mapStatic(m, hs.Cfg.StaticRootPath, "", "public", "/public/views/swagger-template.html") hs.mapStatic(m, hs.Cfg.StaticRootPath, "robots.txt", "robots.txt") if hs.Cfg.ImageUploadProvider == "local" { diff --git a/pkg/plugins/pfs/corelist/corelist_load_gen.go b/pkg/plugins/pfs/corelist/corelist_load_gen.go deleted file mode 100644 index 36864aabe046d..0000000000000 --- a/pkg/plugins/pfs/corelist/corelist_load_gen.go +++ /dev/null @@ -1,90 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. -// -// Generated by: -// public/app/plugins/gen.go -// Using jennies: -// PluginTreeListJenny -// -// Run 'make gen-cue' from repository root to regenerate. - -package corelist - -import ( - "fmt" - "io/fs" - - "github.com/grafana/grafana" - "github.com/grafana/grafana/pkg/plugins/pfs" - "github.com/grafana/thema" -) - -func parsePluginOrPanic(path string, pkgname string, rt *thema.Runtime) pfs.ParsedPlugin { - sub, err := fs.Sub(grafana.CueSchemaFS, path) - if err != nil { - panic("could not create fs sub to " + path) - } - pp, err := pfs.ParsePluginFS(sub, rt, "public/app/plugins/"+pkgname) - if err != nil { - panic(fmt.Sprintf("error parsing plugin metadata for %s: %s", pkgname, err)) - } - return pp -} - -func corePlugins(rt *thema.Runtime) []pfs.ParsedPlugin { - return []pfs.ParsedPlugin{ - parsePluginOrPanic("public/app/plugins/datasource/alertmanager", "alertmanager", rt), - parsePluginOrPanic("public/app/plugins/datasource/azuremonitor", "grafana_azure_monitor_datasource", rt), - parsePluginOrPanic("public/app/plugins/datasource/cloud-monitoring", "stackdriver", rt), - parsePluginOrPanic("public/app/plugins/datasource/cloudwatch", "cloudwatch", rt), - parsePluginOrPanic("public/app/plugins/datasource/dashboard", "dashboard", rt), - parsePluginOrPanic("public/app/plugins/datasource/elasticsearch", "elasticsearch", rt), - parsePluginOrPanic("public/app/plugins/datasource/grafana", "grafana", rt), - parsePluginOrPanic("public/app/plugins/datasource/grafana-pyroscope-datasource", "grafana_pyroscope_datasource", rt), - parsePluginOrPanic("public/app/plugins/datasource/graphite", "graphite", rt), - parsePluginOrPanic("public/app/plugins/datasource/jaeger", "jaeger", rt), - parsePluginOrPanic("public/app/plugins/datasource/loki", "loki", rt), - parsePluginOrPanic("public/app/plugins/datasource/mssql", "mssql", rt), - parsePluginOrPanic("public/app/plugins/datasource/mysql", "mysql", rt), - parsePluginOrPanic("public/app/plugins/datasource/parca", "parca", rt), - parsePluginOrPanic("public/app/plugins/datasource/postgres", "postgres", rt), - parsePluginOrPanic("public/app/plugins/datasource/prometheus", "prometheus", rt), - parsePluginOrPanic("public/app/plugins/datasource/tempo", "tempo", rt), - parsePluginOrPanic("public/app/plugins/datasource/testdata", "testdata", rt), - parsePluginOrPanic("public/app/plugins/datasource/zipkin", "zipkin", rt), - parsePluginOrPanic("public/app/plugins/panel/alertGroups", "alertGroups", rt), - parsePluginOrPanic("public/app/plugins/panel/alertlist", "alertlist", rt), - parsePluginOrPanic("public/app/plugins/panel/annolist", "annolist", rt), - parsePluginOrPanic("public/app/plugins/panel/barchart", "barchart", rt), - parsePluginOrPanic("public/app/plugins/panel/bargauge", "bargauge", rt), - parsePluginOrPanic("public/app/plugins/panel/candlestick", "candlestick", rt), - parsePluginOrPanic("public/app/plugins/panel/canvas", "canvas", rt), - parsePluginOrPanic("public/app/plugins/panel/dashlist", "dashlist", rt), - parsePluginOrPanic("public/app/plugins/panel/datagrid", "datagrid", rt), - parsePluginOrPanic("public/app/plugins/panel/debug", "debug", rt), - parsePluginOrPanic("public/app/plugins/panel/flamegraph", "flamegraph", rt), - parsePluginOrPanic("public/app/plugins/panel/gauge", "gauge", rt), - parsePluginOrPanic("public/app/plugins/panel/geomap", "geomap", rt), - parsePluginOrPanic("public/app/plugins/panel/gettingstarted", "gettingstarted", rt), - parsePluginOrPanic("public/app/plugins/panel/graph", "graph", rt), - parsePluginOrPanic("public/app/plugins/panel/heatmap", "heatmap", rt), - parsePluginOrPanic("public/app/plugins/panel/histogram", "histogram", rt), - parsePluginOrPanic("public/app/plugins/panel/live", "live", rt), - parsePluginOrPanic("public/app/plugins/panel/logs", "logs", rt), - parsePluginOrPanic("public/app/plugins/panel/news", "news", rt), - parsePluginOrPanic("public/app/plugins/panel/nodeGraph", "nodeGraph", rt), - parsePluginOrPanic("public/app/plugins/panel/piechart", "piechart", rt), - parsePluginOrPanic("public/app/plugins/panel/stat", "stat", rt), - parsePluginOrPanic("public/app/plugins/panel/state-timeline", "state_timeline", rt), - parsePluginOrPanic("public/app/plugins/panel/status-history", "status_history", rt), - parsePluginOrPanic("public/app/plugins/panel/table", "table", rt), - parsePluginOrPanic("public/app/plugins/panel/table-old", "table_old", rt), - parsePluginOrPanic("public/app/plugins/panel/text", "text", rt), - parsePluginOrPanic("public/app/plugins/panel/timeseries", "timeseries", rt), - parsePluginOrPanic("public/app/plugins/panel/traces", "traces", rt), - parsePluginOrPanic("public/app/plugins/panel/trend", "trend", rt), - parsePluginOrPanic("public/app/plugins/panel/welcome", "welcome", rt), - parsePluginOrPanic("public/app/plugins/panel/xychart", "xychart", rt), - parsePluginOrPanic("public/app/plugins/datasource/grafadruid-druid-datasource", "grafadruid_druid_datasource", rt), - parsePluginOrPanic("public/app/plugins/panel/sankey-panel-0.5.0", "ismael_sankey_panel", rt), - } -} diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index 8e51e68e558a0..1714ccdedcb83 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -17,9 +17,13 @@ - + - + + + + + diff --git a/public/views/swagger.html b/public/views/swagger.html index 98f9dd49fe64a..79f365ff162a8 100644 --- a/public/views/swagger.html +++ b/public/views/swagger.html @@ -41,4 +41,4 @@ - \ No newline at end of file + diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 5f65e9dcee56f..a0914f22e29c2 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -7,9 +7,12 @@ const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); -const { DefinePlugin } = require('webpack'); +const { DefinePlugin, EnvironmentPlugin } = require('webpack'); +const WebpackAssetsManifest = require('webpack-assets-manifest'); const { merge } = require('webpack-merge'); +const WebpackBar = require('webpackbar'); +const getEnvConfig = require('./env-util.js'); const HTMLWebpackCSSChunks = require('./plugins/HTMLWebpackCSSChunks'); const common = require('./webpack.common.js'); const esbuildTargets = resolveToEsbuildTarget(browserslist(), { printUnknownTargets: false }); @@ -20,6 +23,8 @@ const esbuildOptions = { format: undefined, }; +const envConfig = getEnvConfig(); + module.exports = (env = {}) => { return merge(common, { devtool: 'eval-source-map', @@ -30,6 +35,7 @@ module.exports = (env = {}) => { dark: './public/sass/grafana.dark.scss', light: './public/sass/grafana.light.scss', fn_dashboard: './public/app/fn_dashboard.ts', + swagger: './public/swagger/index.tsx', }, // If we enabled watch option via CLI @@ -128,6 +134,16 @@ module.exports = (env = {}) => { SHOULD_LOG: JSON.stringify('true'), }, }), + new WebpackAssetsManifest({ + entrypoints: true, + integrity: true, + publicPath: true, + }), + new WebpackBar({ + color: '#eb7b18', + name: 'Grafana', + }), + new EnvironmentPlugin(envConfig), ], }); }; diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 435570784b911..1be06aba8c499 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -7,10 +7,11 @@ const { resolveToEsbuildTarget } = require('esbuild-plugin-browserslist'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); -const { DefinePlugin } = require('webpack'); +const { DefinePlugin, EnvironmentPlugin } = require('webpack'); const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); const { merge } = require('webpack-merge'); +const getEnvConfig = require('./env-util.js'); const HTMLWebpackCSSChunks = require('./plugins/HTMLWebpackCSSChunks'); const common = require('./webpack.common.js'); const esbuildTargets = resolveToEsbuildTarget(browserslist(), { printUnknownTargets: false }); @@ -22,6 +23,8 @@ const esbuildOptions = { format: undefined, }; +const envConfig = getEnvConfig(); + module.exports = (env = {}) => merge(common, { mode: 'production', @@ -32,6 +35,7 @@ module.exports = (env = {}) => dark: './public/sass/grafana.dark.scss', light: './public/sass/grafana.light.scss', fn_dashboard: './public/app/fn_dashboard.ts', + swagger: './public/swagger/index.tsx', }, module: { @@ -84,6 +88,13 @@ module.exports = (env = {}) => excludeChunks: ['manifest', 'dark', 'light', 'fn_dashboard'], chunksSortMode: 'none', }), + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/views/swagger.html'), + template: path.resolve(__dirname, '../../public/views/swagger-template.html'), + inject: false, + chunksSortMode: 'none', + excludeChunks: ['dark', 'light', 'fn_dashboard'], + }), // Added fn_dashboard/index.html new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/microfrontends/fn_dashboard/index.html'), @@ -111,5 +122,6 @@ module.exports = (env = {}) => } }); }, + new EnvironmentPlugin(envConfig), ], }); From ea40d07260dad2c981ea8b92598b41c6f97a8684 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Fri, 30 Aug 2024 14:22:57 -0400 Subject: [PATCH 096/101] mfe fix --- .betterer.results | 5 +---- packages/grafana-data/src/types/config.ts | 4 ++++ .../CustomScrollbar/CustomScrollbar.tsx | 13 +++++++++++-- .../src/components/PanelChrome/PanelChrome.tsx | 16 +++++++++++----- public/app/core/internationalization/index.tsx | 2 +- .../dashboard/dashgrid/PanelStateWrapper.tsx | 16 ++++++++++++++-- .../app/features/dashboard/dashgrid/liveTimer.ts | 5 ++++- public/app/fn-app/create-mfe.ts | 2 +- public/app/fn_app.ts | 13 +++++++++++-- public/app/fn_dashboard.ts | 2 +- public/app/types/dashboard.ts | 1 + public/microfrontends/fn_dashboard/index.html | 8 ++------ scripts/webpack/webpack.dev.js | 2 +- 13 files changed, 63 insertions(+), 26 deletions(-) diff --git a/.betterer.results b/.betterer.results index 62ebfad127c80..b6572d2326e0c 100644 --- a/.betterer.results +++ b/.betterer.results @@ -1,5 +1,5 @@ // BETTERER RESULTS V2. -// +// // If this file contains merge conflicts, use `betterer merge` to automatically resolve them: // https://phenomnomnominal.github.io/betterer/docs/results-file/#merge // @@ -3099,9 +3099,6 @@ exports[`better eslint`] = { [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"] - ], "public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], diff --git a/packages/grafana-data/src/types/config.ts b/packages/grafana-data/src/types/config.ts index 1cf37071e2364..bd055036b0468 100644 --- a/packages/grafana-data/src/types/config.ts +++ b/packages/grafana-data/src/types/config.ts @@ -147,6 +147,10 @@ export interface BootData { light: string; dark: string; }; + themePaths: { + dark: string; + light: string; + }; } /** diff --git a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx index 4e66cd7086f2d..f136383d03f49 100644 --- a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx +++ b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx @@ -116,8 +116,17 @@ export const CustomScrollbar = ({ passedProps.style['WebkitOverflowScrolling'] = 'auto'; } - return
; - }, []); + return ( +
+ ); + }, + [divId] + ); const onScrollStop = useCallback(() => { ref.current && setScrollTop && setScrollTop(ref.current.getValues()); diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index e50f103339f1a..96a43f88cd78b 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -23,7 +23,7 @@ import { TitleItem } from './TitleItem'; /** * @internal */ -export type PanelChromeProps = (AutoSize | FixedDimensions) & (Collapsible | HoverHeader); +export type PanelChromeProps = (AutoSize | FixedDimensions) & (Collapsible | HoverHeader) & { isFNPanel?: boolean }; interface BaseProps { padding?: PanelPadding; @@ -134,9 +134,10 @@ export function PanelChrome({ onFocus, onMouseMove, onMouseEnter, + isFNPanel, }: PanelChromeProps) { const theme = useTheme2(); - const styles = useStyles2(getStyles); + const styles = useStyles2(getStyles(isFNPanel)); const panelContentId = useId(); const panelTitleId = useId().replace(/:/g, '_'); @@ -303,7 +304,7 @@ export function PanelChrome({ {headerContent} - {menu && ( + {menu && !isFNPanel && ( { +const getStyles = (isFNPanel?: boolean) => (theme: GrafanaTheme2) => { const { background, borderColor, padding } = theme.components.panel; return { @@ -385,7 +386,7 @@ const getStyles = (theme: GrafanaTheme2) => { backgroundColor: background, border: `1px solid ${borderColor}`, position: 'relative', - borderRadius: theme.shape.radius.default, + borderRadius: theme.shape.borderRadius(), height: '100%', display: 'flex', flexDirection: 'column', @@ -462,6 +463,11 @@ const getStyles = (theme: GrafanaTheme2) => { display: 'flex', padding: theme.spacing(0, padding), minWidth: 0, + ...(isFNPanel && { + width: '100%', + textAlign: 'center', + justifyContent: 'center', + }), '& > h2': { minWidth: 0, }, diff --git a/public/app/core/internationalization/index.tsx b/public/app/core/internationalization/index.tsx index 2d31fc1d70873..006894cdfcae7 100644 --- a/public/app/core/internationalization/index.tsx +++ b/public/app/core/internationalization/index.tsx @@ -78,7 +78,7 @@ export const t = (id: string, defaultMessage: string, values?: Record void; timezone?: string; hideMenu?: boolean; + isFnDashboard?: boolean; } export interface State { @@ -82,7 +85,7 @@ export interface State { liveTime?: TimeRange; } -export class PanelStateWrapper extends PureComponent { +export class PanelStateWrapperDisConnected extends PureComponent { private readonly timeSrv: TimeSrv = getTimeSrv(); private subs = new Subscription(); private eventFilter: EventFilterOptions = { onlyLocal: true }; @@ -555,7 +558,7 @@ export class PanelStateWrapper extends PureComponent { debouncedSetPanelAttention() {} render() { - const { dashboard, panel, width, height, plugin } = this.props; + const { dashboard, panel, width, height, plugin, isFnDashboard } = this.props; const { errorMessage, data } = this.state; const { transparent } = panel; const panelChromeProps = getPanelChromeProps({ ...this.props, data }); @@ -590,6 +593,7 @@ export class PanelStateWrapper extends PureComponent { onFocus={() => this.setPanelAttention()} onMouseEnter={() => this.setPanelAttention()} onMouseMove={() => this.debouncedSetPanelAttention()} + isFNPanel={isFnDashboard} > {(innerWidth, innerHeight) => ( <> @@ -611,3 +615,11 @@ export class PanelStateWrapper extends PureComponent { ); } } + +function mapStateToProps() { + return (state: StoreState) => ({ + isFnDashboard: state.fnGlobalState.FNDashboard, + }); +} + +export const PanelStateWrapper = connect(mapStateToProps)(PanelStateWrapperDisConnected); diff --git a/public/app/features/dashboard/dashgrid/liveTimer.ts b/public/app/features/dashboard/dashgrid/liveTimer.ts index 874bceb245274..8b3866c83abe9 100644 --- a/public/app/features/dashboard/dashgrid/liveTimer.ts +++ b/public/app/features/dashboard/dashgrid/liveTimer.ts @@ -2,7 +2,10 @@ import { BehaviorSubject } from 'rxjs'; import { dateMath, dateTime, TimeRange } from '@grafana/data'; -import { PanelStateWrapper } from './PanelStateWrapper'; +import { PanelStateWrapperDisConnected as Wrapper } from './PanelStateWrapper'; + +type PanelStateWrapper = Wrapper; + // target is 20hz (50ms), but we poll at 100ms to smooth out jitter const interval = 100; diff --git a/public/app/fn-app/create-mfe.ts b/public/app/fn-app/create-mfe.ts index 2c469d86c8288..d6661429f88bc 100644 --- a/public/app/fn-app/create-mfe.ts +++ b/public/app/fn-app/create-mfe.ts @@ -183,7 +183,7 @@ class createMfe { createMfe.removeThemeLinks(createMfe.toggleTheme(mode)); const newCssLink = createMfe.styleSheetLink; - newCssLink.href = config.bootData.assets[mode]; + newCssLink.href = config.bootData.themePaths[mode]; document.body.appendChild(newCssLink); createMfe.logger.info('Successfully loaded theme.', { mode }); diff --git a/public/app/fn_app.ts b/public/app/fn_app.ts index beef41185a3b3..88032cd92d251 100644 --- a/public/app/fn_app.ts +++ b/public/app/fn_app.ts @@ -34,12 +34,14 @@ import { setAppEvents, setPluginExtensionsHook, setPluginComponentHook, + setReturnToPreviousHook, + setChromeHeaderHeightHook, } from '@grafana/runtime'; import { setPanelDataErrorView } from '@grafana/runtime/src/components/PanelDataErrorView'; import { setPanelRenderer } from '@grafana/runtime/src/components/PanelRenderer'; import { setPluginPage } from '@grafana/runtime/src/components/PluginPage'; import { getScrollbarWidth } from '@grafana/ui'; -import config, { Settings } from 'app/core/config'; +import config, { Settings, updateConfig } from 'app/core/config'; import { arrayMove } from 'app/core/utils/arrayMove'; import { getStandardTransformers } from 'app/features/transformers/standardTransformers'; @@ -49,7 +51,7 @@ import appEvents from './core/app_events'; import { AppChromeService } from './core/components/AppChrome/AppChromeService'; import { getAllOptionEditors, getAllStandardFieldConfigs } from './core/components/OptionsUI/registry'; import { PluginPage } from './core/components/Page/PluginPage'; -import { GrafanaContextType } from './core/context/GrafanaContext'; +import { GrafanaContextType, useChromeHeaderHeight, useReturnToPreviousInternal } from './core/context/GrafanaContext'; import { initializeI18n } from './core/internationalization'; import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks'; import { NewFrontendAssetsChecker } from './core/services/NewFrontendAssetsChecker'; @@ -82,6 +84,7 @@ import { preloadPlugins } from './features/plugins/pluginPreloader'; import { QueryRunner } from './features/query/state/QueryRunner'; import { runRequest } from './features/query/state/runRequest'; import { initWindowRuntime } from './features/runtime/init'; +import { initializeScopes } from './features/scopes'; import { variableAdapters } from './features/variables/adapters'; import { createAdHocVariableAdapter } from './features/variables/adhoc/adapter'; import { createConstantVariableAdapter } from './features/variables/constant/adapter'; @@ -118,6 +121,7 @@ export class GrafanaApp { parent.postMessage('GrafanaAppInit', '*'); const initI18nPromise = initializeI18n(config.bootData.user.language); + initI18nPromise.then(({ language }) => updateConfig({ language })); backendSrv.setGrafanaPrefix(true); setBackendSrv(backendSrv); @@ -242,6 +246,11 @@ export class GrafanaApp { config, newAssetsChecker, }; + + setReturnToPreviousHook(useReturnToPreviousInternal); + setChromeHeaderHeightHook(useChromeHeaderHeight); + + initializeScopes(); } catch (error) { console.error('Failed to start Grafana', error); window.__grafana_load_failed(); diff --git a/public/app/fn_dashboard.ts b/public/app/fn_dashboard.ts index 6948289e4a479..e0c198f479eb6 100644 --- a/public/app/fn_dashboard.ts +++ b/public/app/fn_dashboard.ts @@ -20,7 +20,7 @@ declare global { } // config.isPublicDashboardView = false; -config.bootData.assets = window.fnData.assets; +config.bootData.themePaths = window.fnData.assets; export const { bootstrap, mount, unmount, update, afterMount, afterUnmount, beforeLoad, beforeMount, beforeUnmount } = createMfe.create(FNDashboard); diff --git a/public/app/types/dashboard.ts b/public/app/types/dashboard.ts index b480d51b759ee..f98e5f0c8eee9 100644 --- a/public/app/types/dashboard.ts +++ b/public/app/types/dashboard.ts @@ -65,6 +65,7 @@ export interface DashboardMeta { hasUnsavedFolderChange?: boolean; annotationsPermissions?: AnnotationsPermissions; publicDashboardEnabled?: boolean; + publicDashboardAccessToken?: string; dashboardNotFound?: boolean; isEmbedded?: boolean; isNew?: boolean; diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index 1714ccdedcb83..e8803a1f52d4c 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -17,13 +17,9 @@ - + - - - - - + diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index a0914f22e29c2..26756c07a83fb 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -125,7 +125,7 @@ module.exports = (env = {}) => { template: path.resolve(__dirname, '../../public/views/index-microfrontend-template.html'), inject: false, chunksSortMode: 'none', - excludeChunks: ['dark', 'light', 'app'], + excludeChunks: ['dark', 'light', 'app', 'swagger'], }), new HTMLWebpackCSSChunks(), new DefinePlugin({ From 67305b3b4f464d3f93c6fd7d889426f58f26db94 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Mon, 2 Sep 2024 00:33:18 -0400 Subject: [PATCH 097/101] checkpoint --- .coderabbit.yaml | 20 +++ .github/workflows/changelog.yml | 2 + .../deploy-cloud-run-grafana-prod.yaml | 2 +- .../workflows/deploy-cloud-run-grafana.yaml | 2 +- package.json | 2 +- .../grafana-data/src/themes/createShape.ts | 2 +- .../DateTimePicker/DateTimePicker.tsx | 2 +- .../TimeRangePicker/CalendarBody.tsx | 4 + .../TimeRangePicker/TimePickerContent.tsx | 2 +- .../RefreshPicker/RefreshPicker.tsx | 5 +- public/app/fn_dashboard.ts | 4 +- .../app/plugins/panel/canvas/globalStyles.ts | 2 +- public/microfrontends/fn_dashboard/index.html | 29 +---- public/sass/_variables.generated.scss | 4 +- public/views/error.html | 61 +-------- .../views/index-microfrontend-template.html | 2 +- public/views/index.html | 123 +----------------- scripts/webpack/webpack.dev.js | 12 +- scripts/webpack/webpack.prod.js | 28 ++-- 19 files changed, 71 insertions(+), 237 deletions(-) create mode 100644 .coderabbit.yaml diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 0000000000000..29034f7388ed4 --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,20 @@ +# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json +language: "en-US" +early_access: false +reviews: + profile: "chill" + request_changes_workflow: false + high_level_summary: true + poem: true + review_status: true + collapse_walkthrough: false + auto_review: + enabled: true + drafts: false + tools: + golangci-lint: + enabled: true + eslint: + enabled: true +chat: + auto_reply: true diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 48246cc7f425a..33c5cdaed492c 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -38,10 +38,12 @@ on: required: false default: false type: boolean + description: 'Dry run mode' latest: required: false default: false type: boolean + description: 'Generate changelog for the latest release' permissions: contents: write diff --git a/.github/workflows/deploy-cloud-run-grafana-prod.yaml b/.github/workflows/deploy-cloud-run-grafana-prod.yaml index aa0bd33946e73..1e08ef3ee7b51 100644 --- a/.github/workflows/deploy-cloud-run-grafana-prod.yaml +++ b/.github/workflows/deploy-cloud-run-grafana-prod.yaml @@ -3,7 +3,7 @@ name: Deploy Grafana Server Cloud Run on prod on: push: branches: - - fluxninja_micro_frontends + - coderabbit_micro_frontend paths: - "/**" workflow_dispatch: diff --git a/.github/workflows/deploy-cloud-run-grafana.yaml b/.github/workflows/deploy-cloud-run-grafana.yaml index 13b74815feec6..56f45b5aa8248 100644 --- a/.github/workflows/deploy-cloud-run-grafana.yaml +++ b/.github/workflows/deploy-cloud-run-grafana.yaml @@ -3,7 +3,7 @@ name: Deploy Grafana Server Cloud Run on: push: branches: - - fluxninja_micro_frontends + - coderabbit_micro_frontend paths: - "/**" workflow_dispatch: diff --git a/package.json b/package.json index 873c151fdd4e6..85f5c31e4f809 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "version": "11.3.0-pre", "repository": "github:grafana/grafana", "scripts": { - "build": "NODE_ENV=production nx exec --verbose -- webpack --config scripts/webpack/webpack.prod.js", + "build": "NODE_ENV=dev nx exec --verbose -- webpack --config scripts/webpack/webpack.prod.js", "build:nominify": "yarn run build -- --env noMinify=1", "dev": "NODE_ENV=dev nx exec -- webpack --config scripts/webpack/webpack.dev.js", "e2e": "./e2e/start-and-run-suite", diff --git a/packages/grafana-data/src/themes/createShape.ts b/packages/grafana-data/src/themes/createShape.ts index a9159087f05c0..f87ab3d725e83 100644 --- a/packages/grafana-data/src/themes/createShape.ts +++ b/packages/grafana-data/src/themes/createShape.ts @@ -22,7 +22,7 @@ export function createShape(options: ThemeShapeInput): ThemeShape { const baseBorderRadius = options.borderRadius ?? 6; const radius = { - default: '2px', + default: '6px', pill: '9999px', circle: '100%', }; diff --git a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx index 1fdeb14114f11..4eb746fc89be5 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx @@ -381,7 +381,7 @@ const getStyles = (theme: GrafanaTheme2) => ({ container: css({ padding: theme.spacing(1), border: `1px ${theme.colors.border.weak} solid`, - borderRadius: theme.shape.radius.default, + borderRadius: theme.shape.borderRadius(), backgroundColor: theme.colors.background.primary, zIndex: theme.zIndex.modal, }), diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx index a3f988cb3a43d..aedcc536ba91e 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx @@ -111,6 +111,7 @@ export const getBodyStyles = (theme: GrafanaTheme2) => { zIndex: theme.zIndex.modal, backgroundColor: theme.colors.background.primary, width: '268px', + borderRadius: theme.shape.borderRadius(), '.react-calendar__navigation': { display: 'flex', @@ -181,6 +182,9 @@ export const getBodyStyles = (theme: GrafanaTheme2) => { borderTopLeftRadius: '20px', borderBottomLeftRadius: '20px', }, + '& button': { + borderRadius: 0, + }, [`${hasActiveSelector}, .react-calendar__tile--rangeEnd`]: { borderTopRightRadius: '20px', diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx index bb7b75ceb1363..f0b5463ec1000 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx @@ -281,7 +281,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRang background: theme.colors.background.primary, boxShadow: theme.shadows.z3, width: `${isFullscreen ? '546px' : '262px'}`, - borderRadius: theme.shape.radius.default, + borderRadius: theme.shape.borderRadius(), border: `1px solid ${theme.colors.border.weak}`, [`${isReversed ? 'left' : 'right'}`]: 0, }), diff --git a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx index d207288ba891d..d6d15ee929842 100644 --- a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx +++ b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx @@ -5,7 +5,6 @@ import { SelectableValue, parseDuration } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { t } from '../../utils/i18n'; -import { ButtonGroup } from '../Button'; import { ButtonSelect } from '../Dropdown/ButtonSelect'; import { ToolbarButtonVariant, ToolbarButton } from '../ToolbarButton'; @@ -102,7 +101,7 @@ export class RefreshPicker extends PureComponent { const tooltipAutoRefresh = selectedValue.value === '' ? tooltipAutoRefreshOff : tooltipIntervalSelected; return ( - +
{ tooltip={tooltipAutoRefresh} /> )} - +
); } } diff --git a/public/app/fn_dashboard.ts b/public/app/fn_dashboard.ts index e0c198f479eb6..360a559c8fbf8 100644 --- a/public/app/fn_dashboard.ts +++ b/public/app/fn_dashboard.ts @@ -7,7 +7,7 @@ config.featureToggles = { publicDashboards: true, }; interface FnData { - assets: { + themePaths: { light: string; dark: string; }; @@ -20,7 +20,7 @@ declare global { } // config.isPublicDashboardView = false; -config.bootData.themePaths = window.fnData.assets; +config.bootData.themePaths = window.fnData.themePaths; export const { bootstrap, mount, unmount, update, afterMount, afterUnmount, beforeLoad, beforeMount, beforeUnmount } = createMfe.create(FNDashboard); diff --git a/public/app/plugins/panel/canvas/globalStyles.ts b/public/app/plugins/panel/canvas/globalStyles.ts index a61d39d39d54d..fdaca50fc1159 100644 --- a/public/app/plugins/panel/canvas/globalStyles.ts +++ b/public/app/plugins/panel/canvas/globalStyles.ts @@ -77,7 +77,7 @@ export function getGlobalStyles(theme: GrafanaTheme2) { cursor: 'grab', flexGrow: 1, border: `1px solid ${theme.components.input.borderColor}`, - borderRadius: `${theme.shape.radius.default}`, + borderRadius: `${theme.shape.borderRadius()}`, background: `${theme.colors.background.secondary}`, minHeight: `${theme.spacing.gridSize * 4}px`, '&:hover': { diff --git a/public/microfrontends/fn_dashboard/index.html b/public/microfrontends/fn_dashboard/index.html index e8803a1f52d4c..58bde6455b7c9 100644 --- a/public/microfrontends/fn_dashboard/index.html +++ b/public/microfrontends/fn_dashboard/index.html @@ -1,25 +1,6 @@ - - - - CodeRabbit Micro-frontend - - - - -
- - - - - - - - - + }; \ No newline at end of file diff --git a/public/sass/_variables.generated.scss b/public/sass/_variables.generated.scss index ee0561eb84645..af4b049cb217d 100644 --- a/public/sass/_variables.generated.scss +++ b/public/sass/_variables.generated.scss @@ -132,9 +132,9 @@ $headings-line-height: 1.5 !default; $border-width: 1px !default; -$border-radius: 2px !default; +$border-radius: 6px !default; $border-radius-lg: 18px !default; -$border-radius-sm: 2px !default; +$border-radius-sm: 6px !default; // Page diff --git a/public/views/error.html b/public/views/error.html index 1eb195cd125b9..9e8fe69e60614 100644 --- a/public/views/error.html +++ b/public/views/error.html @@ -1,60 +1 @@ - - - - - - - - - [[.AppTitle]] - Error - - - - [[ if eq .ThemeType "light" ]] - - [[ else ]] - - [[ end ]] - - - - - - -
-
- -
-
-
-
-
-
[[.Title]]
-
-
-
- [[if .ErrorMsg]] -

Error details

-
-
[[.ErrorMsg]]
-
- [[end]] -
-

Check the Grafana server logs for the detailed error message.

-
-
-
- - +[[.AppTitle]] - Error[[ if eq .ThemeType "light" ]][[ else ]][[ end ]]
[[.Title]]

[[if .ErrorMsg]]

Error details

[[.ErrorMsg]]
[[end]]

Check the Grafana server logs for the detailed error message.

\ No newline at end of file diff --git a/public/views/index-microfrontend-template.html b/public/views/index-microfrontend-template.html index a59112abe3a3d..4eb1d8a0cd03b 100644 --- a/public/views/index-microfrontend-template.html +++ b/public/views/index-microfrontend-template.html @@ -9,7 +9,7 @@
- - - - - - - - - - -
-
-
- -
-
-
-

- If you're seeing this Grafana has failed to load its application files -
-
-

-

- 1. This could be caused by your reverse proxy settings.

- 2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath. If not - using a reverse proxy make sure to set serve_from_sub_path to true.
-
- 3. If you have a local dev build make sure you build frontend using: yarn start, or yarn build
-
- 4. Sometimes restarting grafana-server can help
-
- 5. Check if you are using a non-supported browser. For more information, refer to the list of - - supported browsers. -

-
- -
- -
- -
- - [[if .GoogleTagManagerId]] - - [[if .GoogleTagManagerId]] - - - - [[end]] - - [[range $asset := .Assets.JSFiles]] - - [[end]] - - - - + })(window, document, 'script', 'dataLayer', '[[.GoogleTagManagerId]]');[[end]] [[range $asset := .Assets.JSFiles]][[end]] \ No newline at end of file diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 26756c07a83fb..63cb0eeb134c4 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -128,12 +128,6 @@ module.exports = (env = {}) => { excludeChunks: ['dark', 'light', 'app', 'swagger'], }), new HTMLWebpackCSSChunks(), - new DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify('development'), - SHOULD_LOG: JSON.stringify('true'), - }, - }), new WebpackAssetsManifest({ entrypoints: true, integrity: true, @@ -144,6 +138,12 @@ module.exports = (env = {}) => { name: 'Grafana', }), new EnvironmentPlugin(envConfig), + new DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('development'), + SHOULD_LOG: JSON.stringify('true'), + }, + }), ], }); }; diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 1be06aba8c499..9901d78caface 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -8,6 +8,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); const { DefinePlugin, EnvironmentPlugin } = require('webpack'); +const WebpackAssetsManifest = require('webpack-assets-manifest'); const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); const { merge } = require('webpack-merge'); @@ -78,37 +79,28 @@ module.exports = (env = {}) => filename: path.resolve(__dirname, '../../public/views/error.html'), template: path.resolve(__dirname, '../../public/views/error-template.html'), inject: false, - excludeChunks: ['dark', 'light', 'fn_dashboard'], chunksSortMode: 'none', + excludeChunks: ['dark', 'light', 'fn_dashboard'], }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/views/index.html'), template: path.resolve(__dirname, '../../public/views/index-template.html'), inject: false, - excludeChunks: ['manifest', 'dark', 'light', 'fn_dashboard'], - chunksSortMode: 'none', - }), - new HtmlWebpackPlugin({ - filename: path.resolve(__dirname, '../../public/views/swagger.html'), - template: path.resolve(__dirname, '../../public/views/swagger-template.html'), - inject: false, chunksSortMode: 'none', excludeChunks: ['dark', 'light', 'fn_dashboard'], }), - // Added fn_dashboard/index.html new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/microfrontends/fn_dashboard/index.html'), template: path.resolve(__dirname, '../../public/views/index-microfrontend-template.html'), inject: false, chunksSortMode: 'none', - excludeChunks: ['dark', 'light', 'app'], + excludeChunks: ['dark', 'light', 'app', 'swagger'], }), new HTMLWebpackCSSChunks(), - new DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify('development'), - SHOULD_LOG: JSON.stringify('false'), - }, + new WebpackAssetsManifest({ + entrypoints: true, + integrity: true, + publicPath: true, }), new WebpackManifestPlugin({ fileName: path.join(process.cwd(), 'manifest.json'), @@ -123,5 +115,11 @@ module.exports = (env = {}) => }); }, new EnvironmentPlugin(envConfig), + new DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('development'), + SHOULD_LOG: JSON.stringify('false'), + }, + }), ], }); From 3b25e72e23a06e6270b5a6c5c1310a53ae6930c5 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Tue, 3 Sep 2024 12:13:33 -0400 Subject: [PATCH 098/101] tooltip, icons fix --- .coderabbit.yaml | 20 - package.json | 2 +- .../TimeRangePicker/TimeRangeContent.tsx | 4 +- .../src/components/Dropdown/ButtonSelect.tsx | 1 + .../grafana-ui/src/components/Icon/Icon.tsx | 62 +- .../uPlot/plugins/TooltipPlugin2.tsx | 27 +- pkg/services/ldap/ldap_login_test.go | 258 - pkg/services/ldap/ldap_private_test.go | 283 - pkg/services/ldap/ldap_test.go | 647 -- .../dashboard/components/DashNav/DashNav.tsx | 75 +- .../components/DashNav/ShareButton.tsx | 15 +- scripts/webpack/webpack.prod.js | 20 +- yarn.lock | 6293 +++++++++-------- 13 files changed, 3321 insertions(+), 4386 deletions(-) delete mode 100644 .coderabbit.yaml delete mode 100644 pkg/services/ldap/ldap_login_test.go delete mode 100644 pkg/services/ldap/ldap_private_test.go delete mode 100644 pkg/services/ldap/ldap_test.go diff --git a/.coderabbit.yaml b/.coderabbit.yaml deleted file mode 100644 index 29034f7388ed4..0000000000000 --- a/.coderabbit.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json -language: "en-US" -early_access: false -reviews: - profile: "chill" - request_changes_workflow: false - high_level_summary: true - poem: true - review_status: true - collapse_walkthrough: false - auto_review: - enabled: true - drafts: false - tools: - golangci-lint: - enabled: true - eslint: - enabled: true -chat: - auto_reply: true diff --git a/package.json b/package.json index 85f5c31e4f809..873c151fdd4e6 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "version": "11.3.0-pre", "repository": "github:grafana/grafana", "scripts": { - "build": "NODE_ENV=dev nx exec --verbose -- webpack --config scripts/webpack/webpack.prod.js", + "build": "NODE_ENV=production nx exec --verbose -- webpack --config scripts/webpack/webpack.prod.js", "build:nominify": "yarn run build -- --env noMinify=1", "dev": "NODE_ENV=dev nx exec -- webpack --config scripts/webpack/webpack.dev.js", "e2e": "./e2e/start-and-run-suite", diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx index 46d43108c1db2..1f3f5e1eff7d5 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx @@ -218,9 +218,9 @@ export const TimeRangeContent = (props: Props) => { type="button" onClick={onApply} style={{ - width: '100%', + width: 193, textAlign: 'center', - paddingLeft: '55px', + paddingLeft: 45, }} > Apply time range diff --git a/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx b/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx index 719a32bcb382d..883f7b645ab0d 100644 --- a/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx +++ b/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx @@ -128,6 +128,7 @@ const getStyles = (theme: GrafanaTheme2) => { }), menuWrapper: css({ zIndex: theme.zIndex.dropdown, + marginLeft: -25, }), }; }; diff --git a/packages/grafana-ui/src/components/Icon/Icon.tsx b/packages/grafana-ui/src/components/Icon/Icon.tsx index d760c3a318587..bb810b87732ca 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.tsx +++ b/packages/grafana-ui/src/components/Icon/Icon.tsx @@ -42,6 +42,7 @@ const getIconStyles = (theme: GrafanaTheme2) => { }; }; +const cachedIcon = new Map(); export const Icon = React.forwardRef( ({ size = 'md', type = 'default', name, className, style, title = '', ...rest }, ref) => { const styles = useStyles2(getIconStyles); @@ -58,7 +59,28 @@ export const Icon = React.forwardRef( const svgHgt = svgSize; const svgWid = name.startsWith('gf-bar-align') ? 16 : name.startsWith('gf-interp') ? 30 : svgSize; const subDir = getIconSubDir(iconName, type); - const svgPath = `${iconRoot}${subDir}/${iconName}.svg`; + const [svgPath, setSvgPath] = React.useState(null); + + React.useEffect(() => { + const iconPath = `${iconRoot}${subDir}/${iconName}.svg`; + if (cachedIcon.has(iconPath)) { + setSvgPath(cachedIcon.get(iconPath)); + return; + } + /** + * For microfrontend, all the Grafana routes are behind the proxy, so we need to fetch the icon from the proxy. + * When we use fetch request get intercepted and url is changed to the proxy url. + */ + fetch(iconPath).then(async (response) => { + if (response.ok) { + const icon = await response.text(); + cachedIcon.set(iconPath, icon); + setSvgPath(icon); + } else { + console.error(`Icon ${iconName} not found`); + } + }); + }, [iconName, iconRoot, subDir]); const composedClassName = cx( styles.icon, @@ -70,23 +92,27 @@ export const Icon = React.forwardRef( ); return ( - + <> + {svgPath && ( + + )} + ); } ); diff --git a/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx b/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx index 54b6648efefbc..3e916bc8e1ebb 100644 --- a/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx +++ b/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx @@ -1,7 +1,6 @@ import { css, cx } from '@emotion/css'; import { useLayoutEffect, useRef, useReducer, CSSProperties } from 'react'; import * as React from 'react'; -import { createPortal } from 'react-dom'; import uPlot from 'uplot'; import { GrafanaTheme2 } from '@grafana/data'; @@ -9,7 +8,7 @@ import { DashboardCursorSync } from '@grafana/schema'; import { useStyles2 } from '../../../themes'; import { RangeSelection1D, RangeSelection2D, OnSelectRangeCallback } from '../../PanelChrome'; -import { getPortalContainer } from '../../Portal/Portal'; +import { getPortalContainer, Portal } from '../../Portal/Portal'; import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder'; import { CloseButton } from './CloseButton'; @@ -651,18 +650,18 @@ export const TooltipPlugin2 = ({ }, [isHovering]); if (plot && isHovering) { - return createPortal( -
- {isPinned && } - {contents} -
, - portalRoot.current + return ( + +
+ {isPinned && } + {contents} +
+
); } diff --git a/pkg/services/ldap/ldap_login_test.go b/pkg/services/ldap/ldap_login_test.go deleted file mode 100644 index 11d1d8a6cfc13..0000000000000 --- a/pkg/services/ldap/ldap_login_test.go +++ /dev/null @@ -1,258 +0,0 @@ -package ldap - -import ( - "errors" - "testing" - - "github.com/go-ldap/ldap/v3" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/login" -) - -var defaultLogin = &login.LoginUserQuery{ - Username: "user", - Password: "pwd", - IpAddress: "192.168.1.1:56433", -} - -func TestServer_Login_UserBind_Fail(t *testing.T) { - connection := &MockConnection{} - entry := ldap.Entry{} - result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}} - connection.setSearchResult(&result) - - connection.BindProvider = func(username, password string) error { - return &ldap.Error{ - ResultCode: 49, - } - } - - cfg := &Config{ - Enabled: true, - } - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: connection, - log: log.New("test-logger"), - } - - _, err := server.Login(defaultLogin) - - assert.ErrorIs(t, err, ErrInvalidCredentials) -} - -func TestServer_Login_Search_NoResult(t *testing.T) { - connection := &MockConnection{} - result := ldap.SearchResult{Entries: []*ldap.Entry{}} - connection.setSearchResult(&result) - - connection.BindProvider = func(username, password string) error { - return nil - } - server := &Server{ - Config: &ServerConfig{ - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: connection, - log: log.New("test-logger"), - } - - _, err := server.Login(defaultLogin) - assert.ErrorIs(t, err, ErrCouldNotFindUser) -} - -func TestServer_Login_Search_Error(t *testing.T) { - connection := &MockConnection{} - expected := errors.New("Killa-gorilla") - connection.setSearchError(expected) - - connection.BindProvider = func(username, password string) error { - return nil - } - server := &Server{ - Config: &ServerConfig{ - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: connection, - log: log.New("test-logger"), - } - - _, err := server.Login(defaultLogin) - assert.ErrorIs(t, err, expected) -} - -func TestServer_Login_ValidCredentials(t *testing.T) { - connection := &MockConnection{} - entry := ldap.Entry{ - DN: "dn", Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"markelog"}}, - {Name: "surname", Values: []string{"Gaidarenko"}}, - {Name: "email", Values: []string{"markelog@gmail.com"}}, - {Name: "name", Values: []string{"Oleg"}}, - {Name: "memberof", Values: []string{"admins"}}, - }, - } - result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}} - connection.setSearchResult(&result) - - connection.BindProvider = func(username, password string) error { - return nil - } - - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Attr: AttributeMap{ - Username: "username", - Name: "name", - MemberOf: "memberof", - }, - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: connection, - log: log.New("test-logger"), - } - - resp, err := server.Login(defaultLogin) - require.NoError(t, err) - assert.Equal(t, "markelog", resp.Login) -} - -// TestServer_Login_UnauthenticatedBind tests that unauthenticated bind -// is called when there is no admin password or user wildcard in the -// bind_dn. -func TestServer_Login_UnauthenticatedBind(t *testing.T) { - connection := &MockConnection{} - entry := ldap.Entry{ - DN: "test", - } - result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}} - connection.setSearchResult(&result) - - connection.UnauthenticatedBindProvider = func() error { - return nil - } - - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: connection, - log: log.New("test-logger"), - } - - user, err := server.Login(defaultLogin) - require.NoError(t, err) - assert.Equal(t, "test", user.AuthId) - assert.True(t, connection.UnauthenticatedBindCalled) -} - -func TestServer_Login_AuthenticatedBind(t *testing.T) { - connection := &MockConnection{} - entry := ldap.Entry{ - DN: "test", - } - result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}} - connection.setSearchResult(&result) - - adminUsername := "" - adminPassword := "" - username := "" - password := "" - - i := 0 - connection.BindProvider = func(name, pass string) error { - i++ - if i == 1 { - adminUsername = name - adminPassword = pass - } - - if i == 2 { - username = name - password = pass - } - - return nil - } - - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - BindDN: "killa", - BindPassword: "gorilla", - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: connection, - log: log.New("test-logger"), - } - - user, err := server.Login(defaultLogin) - require.NoError(t, err) - - assert.Equal(t, "test", user.AuthId) - assert.True(t, connection.BindCalled) - - assert.Equal(t, "killa", adminUsername) - assert.Equal(t, "gorilla", adminPassword) - - assert.Equal(t, "test", username) - assert.Equal(t, "pwd", password) -} - -func TestServer_Login_UserWildcardBind(t *testing.T) { - connection := &MockConnection{} - entry := ldap.Entry{ - DN: "test", - } - connection.setSearchResult(&ldap.SearchResult{Entries: []*ldap.Entry{&entry}}) - - authBindUser := "" - authBindPassword := "" - - connection.BindProvider = func(name, pass string) error { - authBindUser = name - authBindPassword = pass - return nil - } - - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - BindDN: "cn=%s,ou=users,dc=grafana,dc=org", - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: connection, - log: log.New("test-logger"), - } - - _, err := server.Login(defaultLogin) - require.NoError(t, err) - - assert.Equal(t, "cn=user,ou=users,dc=grafana,dc=org", authBindUser) - assert.Equal(t, "pwd", authBindPassword) - assert.True(t, connection.BindCalled) -} diff --git a/pkg/services/ldap/ldap_private_test.go b/pkg/services/ldap/ldap_private_test.go deleted file mode 100644 index 6dc52c19ba7c2..0000000000000 --- a/pkg/services/ldap/ldap_private_test.go +++ /dev/null @@ -1,283 +0,0 @@ -package ldap - -import ( - "testing" - - "github.com/go-ldap/ldap/v3" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/login" - "github.com/grafana/grafana/pkg/services/org" -) - -func TestServer_getSearchRequest(t *testing.T) { - expected := &ldap.SearchRequest{ - BaseDN: "killa", - Scope: 2, - DerefAliases: 0, - SizeLimit: 0, - TimeLimit: 0, - TypesOnly: false, - Filter: "(|)", - Attributes: []string{ - "username", - "email", - "name", - "memberof", - "gansta", - }, - Controls: nil, - } - - server := &Server{ - Config: &ServerConfig{ - Attr: AttributeMap{ - Username: "username", - Name: "name", - MemberOf: "memberof", - Email: "email", - }, - GroupSearchFilterUserAttribute: "gansta", - SearchBaseDNs: []string{"BaseDNHere"}, - }, - log: log.New("test-logger"), - } - - result := server.getSearchRequest("killa", []string{"gorilla"}) - - assert.EqualValues(t, expected, result) -} - -func TestSerializeUsers(t *testing.T) { - t.Run("simple case", func(t *testing.T) { - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Attr: AttributeMap{ - Username: "username", - Name: "name", - MemberOf: "memberof", - Email: "email", - }, - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: &MockConnection{}, - log: log.New("test-logger"), - } - - entry := ldap.Entry{ - DN: "dn", - Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"roelgerrits"}}, - {Name: "surname", Values: []string{"Gerrits"}}, - {Name: "email", Values: []string{"roel@test.com"}}, - {Name: "name", Values: []string{"Roel"}}, - {Name: "memberof", Values: []string{"admins"}}, - }, - } - users := [][]*ldap.Entry{{&entry}} - - result, err := server.serializeUsers(users) - require.NoError(t, err) - - assert.Equal(t, "roelgerrits", result[0].Login) - assert.Equal(t, "roel@test.com", result[0].Email) - assert.Contains(t, result[0].Groups, "admins") - }) - - t.Run("without lastname", func(t *testing.T) { - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Attr: AttributeMap{ - Username: "username", - Name: "name", - MemberOf: "memberof", - Email: "email", - }, - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: &MockConnection{}, - log: log.New("test-logger"), - } - - entry := ldap.Entry{ - DN: "dn", - Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"roelgerrits"}}, - {Name: "email", Values: []string{"roel@test.com"}}, - {Name: "name", Values: []string{"Roel"}}, - {Name: "memberof", Values: []string{"admins"}}, - }, - } - users := [][]*ldap.Entry{{&entry}} - - result, err := server.serializeUsers(users) - require.NoError(t, err) - - assert.False(t, result[0].IsDisabled) - assert.Equal(t, "Roel", result[0].Name) - }) - - t.Run("mark user without matching group as disabled", func(t *testing.T) { - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Groups: []*GroupToOrgRole{{ - GroupDN: "foo", - OrgId: 1, - OrgRole: org.RoleEditor, - }}, - }, - Connection: &MockConnection{}, - log: log.New("test-logger"), - } - - entry := ldap.Entry{ - DN: "dn", - Attributes: []*ldap.EntryAttribute{ - {Name: "memberof", Values: []string{"admins"}}, - }, - } - users := [][]*ldap.Entry{{&entry}} - - result, err := server.serializeUsers(users) - require.NoError(t, err) - - assert.Len(t, result, 1) - assert.True(t, result[0].IsDisabled) - }) -} - -func TestServer_validateGrafanaUser(t *testing.T) { - t.Run("no group config", func(t *testing.T) { - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Groups: []*GroupToOrgRole{}, - }, - log: logger.New("test"), - } - - user := &login.ExternalUserInfo{ - Login: "markelog", - } - - err := server.validateGrafanaUser(user) - require.NoError(t, err) - }) - - t.Run("user in group", func(t *testing.T) { - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Groups: []*GroupToOrgRole{ - { - OrgId: 1, - }, - }, - }, - log: logger.New("test"), - } - - user := &login.ExternalUserInfo{ - Login: "markelog", - OrgRoles: map[int64]org.RoleType{ - 1: "test", - }, - } - - err := server.validateGrafanaUser(user) - require.NoError(t, err) - }) - - t.Run("user not in group", func(t *testing.T) { - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Groups: []*GroupToOrgRole{ - { - OrgId: 1, - }, - }, - }, - log: logger.New("test"), - } - - user := &login.ExternalUserInfo{ - Login: "markelog", - } - - err := server.validateGrafanaUser(user) - require.ErrorIs(t, err, ErrInvalidCredentials) - }) -} - -func TestServer_binds(t *testing.T) { - t.Run("single bind with cn wildcard", func(t *testing.T) { - server := &Server{ - Config: &ServerConfig{ - BindDN: "cn=%s,dc=grafana,dc=org", - }, - } - - assert.True(t, server.shouldSingleBind()) - assert.Equal(t, "cn=test,dc=grafana,dc=org", server.singleBindDN("test")) - }) - - t.Run("don't single bind", func(t *testing.T) { - server := &Server{ - Config: &ServerConfig{ - BindDN: "cn=admin,dc=grafana,dc=org", - }, - } - - assert.False(t, server.shouldSingleBind()) - }) - - t.Run("admin user bind", func(t *testing.T) { - server := &Server{ - Config: &ServerConfig{ - BindPassword: "test", - }, - } - - assert.True(t, server.shouldAdminBind()) - }) - - t.Run("don't admin user bind", func(t *testing.T) { - server := &Server{ - Config: &ServerConfig{ - BindPassword: "", - }, - } - - assert.False(t, server.shouldAdminBind()) - }) -} diff --git a/pkg/services/ldap/ldap_test.go b/pkg/services/ldap/ldap_test.go deleted file mode 100644 index b67686654184c..0000000000000 --- a/pkg/services/ldap/ldap_test.go +++ /dev/null @@ -1,647 +0,0 @@ -package ldap - -import ( - "errors" - "fmt" - "testing" - - "github.com/go-ldap/ldap/v3" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/apimachinery/identity" - "github.com/grafana/grafana/pkg/infra/log" -) - -const ( - validCert = `LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURYVENDQWtXZ0F3SUJBZ0lKQUxtVlZ1RFd1NE5ZTUEwR0NTcUdTSWIzRFFFQkN -3VUFNRVV4Q3pBSkJnTlYKQkFZVEFrRlZNUk13RVFZRFZRUUlEQXBUYjIxbExWTjBZWFJsTVNFd0h3WURWUVFLREJoSmJuUmxjbTVsZENCWAphV1JuYVhSekl -GQjBlU0JNZEdRd0hoY05NVFl4TWpNeE1UUXpORFEzV2hjTk5EZ3dOakkxTVRRek5EUTNXakJGCk1Rc3dDUVlEVlFRR0V3SkJWVEVUTUJFR0ExVUVDQXdLVTI -5dFpTMVRkR0YwWlRFaE1COEdBMVVFQ2d3WVNXNTAKWlhKdVpYUWdWMmxrWjJsMGN5QlFkSGtnVEhSa01JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUTh -BTUlJQgpDZ0tDQVFFQXpVQ0ZvemdOYjFoMU0wanpOUlNDamhPQm5SK3VWYlZwYVdmWFlJUitBaFdEZEVlNXJ5WStDZ2F2Ck9nOGJmTHlieXpGZGVobFlkRFJ -na2VkRUIvR2pHOGFKdzA2bDBxRjRqRE9BdzBrRXlnV0N1Mm1jSDdYT3hSdCsKWUFIM1RWSGEvSHUxVzNXanprb2JxcXFMUThna0tXV00yN2ZPZ0FaNkdpZWF -KQk42VkJTTU1jUGV5M0hXTEJtYworVFlKbXYxZGJhTzJqSGhLaDhwZkt3MFcxMlZNOFAxUElPOGd2NFBodS91dUpZaWVCV0tpeEJFeXkwbEhqeWl4CllGQ1I -xMnhkaDRDQTQ3cTk1OFpSR25uRFVHRlZFMVFoZ1JhY0pDT1o5YmQ1dDltcjhLTGFWQllUQ0pvNUVSRTgKanltYWI1ZFBxZTVxS2ZKc0NaaXFXZ2xialVvOXR -3SURBUUFCbzFBd1RqQWRCZ05WSFE0RUZnUVV4cHV3Y3MvQwpZUU95dWkrcjFHKzNLeEJOaHhrd0h3WURWUjBqQkJnd0ZvQVV4cHV3Y3MvQ1lRT3l1aStyMUc -rM0t4Qk5oeGt3CkRBWURWUjBUQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBQWlXVUtzLzJ4L3ZpTkNLaTNZNmIKbEV1Q3RBR2h6T09aOUV -qcnZKOCtDT0gzUmFnM3RWQldyY0JaMy91aGhQcTVneTlscXc0T2t2RXdzOTkvNWpGcwpYMUZKNk1LQmdxZnV5N3loNXMxWWZNMEFOSFljek1tWXBaZUFjUWY -yQ0dBYVZmd1RUZlNsek5Mc0YybFcvbHk3CnlhcEZ6bFlTSkxHb1ZFK09IRXU4ZzVTbE5BQ1VFZmtYdys1RWdoaCtLemxJTjdSNlE3cjJpeFdORkJDL2pXZjc -KTktVZkp5WDhxSUc1bWQxWVVlVDZHQlc5Qm0yLzEvUmlPMjRKVGFZbGZMZEtLOVRZYjhzRzVCK09MYWIyREltRwo5OUNKMjVSa0FjU29iV05GNXpEME82bGd -PbzNjRWRCL2tzQ3EzaG10bEMvRGxMWi9EOENKKzdWdVpuUzFyUjJuCmFRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==` - validKey = `LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFdlFJQkFEQU5CZ2txaGtpRzl3MEJBUUVGQUFTQ0JLY3dnZ1NqQWdFQUFv -SUJBUUROUUlXak9BMXZXSFV6ClNQTTFGSUtPRTRHZEg2NVZ0V2xwWjlkZ2hINENGWU4wUjdtdkpqNEtCcTg2RHh0OHZKdkxNVjE2R1ZoME5HQ1IKNTBRSDhh -TWJ4b25EVHFYU29YaU1NNEREU1FUS0JZSzdhWndmdGM3RkczNWdBZmROVWRyOGU3VmJkYVBPU2h1cQpxb3REeUNRcFpZemJ0ODZBQm5vYUo1b2tFM3BVRkl3 -eHc5N0xjZFlzR1p6NU5nbWEvVjF0bzdhTWVFcUh5bDhyCkRSYlhaVXp3L1U4Zzd5Qy9nK0c3KzY0bGlKNEZZcUxFRVRMTFNVZVBLTEZnVUpIWGJGMkhnSURq -dXIzbnhsRWEKZWNOUVlWVVRWQ0dCRnB3a0k1bjF0M20zMmF2d290cFVGaE1JbWprUkVUeVBLWnB2bDArcDdtb3A4bXdKbUtwYQpDVnVOU2oyM0FnTUJBQUVD -Z2dFQUJuNEkvQjIweHhYY056QVNpVlpKdnVhOURkUkh0bXhUbGtMem5CajB4Mm9ZCnkxL05iczNkM29GUm41dUV1aEJaT1RjcGhzZ3dkUlNIRFhac1AzZ1VP -YmV3K2QyTi96aWVVSWo4aExEVmx2SlAKclUvczRVL2w1M1EwTGlOQnlFOVRodkwrekpMUENLSnRkNXVIWmpCNWZGbTY5K1E3Z3U4eGc0eEhJdWIrMHBQNQpQ -SGFubUhDRHJiZ05OL29xbGFyNEZaMk1YVGdla1c2QW15Yy9rb0U5aEluNEJhYTJLZS9CL0FVR1k0cE1STHFwClRBcnQrR1RWZVdlb0ZZOVFBQ1VwYUhwSmhH -Yi9QaW91NnRsVTU3ZTQyY0xva2kxZjArU0FSc0JCS3lYQTdCQjEKMWZNSDEwS1FZRkE2OGRUWVdsS3pRYXUvSzR4YXFnNEZLbXR3RjY2R1FRS0JnUUQ5T3BO -VVM3b1J4TUhWSmFCUgpUTldXK1YxRlh5Y3FvamVrRnBEaWpQYjJYNUNXVjE2b2VXZ2FYcDBuT0hGZHk5RVdzM0d0R3BmWmFzYVJWSHNYClNIdFBoNE5iOEpx -SGRHRTAvQ0Q2dDArNERuczhCbjljU3F0ZFFCN1IzSm43SU1YaTlYL1U4TERLbytBMTgvSnEKVjhWZ1VuZ01ueTlZak1rUUliSzhUUldrWVFLQmdRRFBmNG54 -TzZqdSt0T0hIT1JRdHkzYllERDArT1YzSTArTAoweXowdVByZXJ5QlZpOW5ZNDNLYWtINTJEN1VaRXd3c0JqakdYRCtXSDh4RXNtQldzR05YSnUwMjVQdnpJ -Sm96CmxBRWlYdk1wL05tWXArdFk0ckRtTzhSaHlWb2NCcVdIemgzOG0wSUZPZDRCeUZENW5MRURyQTNwRFZvMGFOZ1kKbjBHd1J5c1pGd0tCZ1FEa0NqM202 -Wk1Vc1VXRXR5K2FSMEVKaG1LeU9EQkRPblkwOUlWaEgyUy9GZXhWRnpVTgpMdGZLOTIwNmhwL0F3ZXozTG4ydVQ0WnpxcTVLN2ZNelVuaUpkQldkVkIwMDRs -OHZvZVhwSWU5T1p1d2ZjQko5CmdGaTF6eXB4L3VGRHY0MjFCelFwQk4rUWZPZEtidmJkUVZGam5xQ3hiU0RyODB5VmxHTXJJNWZid1FLQmdHMDkKb1JyZXBP -N0VJTzhHTi9HQ3J1TEsvcHRLR2t5aHkzUTZ4blZFbWRiNDdoWDduY0pBNUlvWlBtcmJsQ1ZTVU5zdwpuMTFYSGFia3NMOE9CZ2c5cnQ4b1FFVGhRdi9hRHpU -T1c5YURsSk5yYWdlamlCVHdxOTlhWWVaMWdqbzFDWnE0CjJqS3VicENmeVpDNHJHRHRySWZaWWkxcStTMlVjUWh0ZDhEZGh3UWJBb0dBQU00RXBEQTR5SEI1 -eWllazFwL28KQ2JxUkN0YS9EeDZFeW8wS2xOQXlQdUZQQXNodXBHNE5CeDdtVDJBU2ZMKzJWQkhvaTZtSFNyaStCRFg1cnlZRgpmTVl2cDdVUllvcTd3N3Fp -dlJsdnZFZzV5b1lySzEzRjIrR2o2eEo0akVOOW0wS2RNL2czbUpHcTBIQlRJUXJwClNtNzVXWHNmbE94dVRuMDhMYmdHYzRzPQotLS0tLUVORCBSU0EgUFJJ -VkFURSBLRVktLS0tLQ==` -) - -func TestNew(t *testing.T) { - result := New(&ServerConfig{ - Attr: AttributeMap{}, - SearchBaseDNs: []string{"BaseDNHere"}, - }, &Config{}) - - assert.Implements(t, (*IServer)(nil), result) -} - -func TestServer_Dial(t *testing.T) { - t.Run("fails having no host but with valid root and client certificate files", func(t *testing.T) { - serverConfig := &ServerConfig{ - Host: "", - RootCACert: "./testdata/parsable.cert", - ClientCert: "./testdata/parsable.cert", - ClientKey: "./testdata/parsable.pem", - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "connect") - }) - - t.Run("fails with invalid root certificate file", func(t *testing.T) { - serverConfig := &ServerConfig{ - RootCACert: "./testdata/invalid.cert", - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "failed to append CA certificate") - }) - - t.Run("fails with non existing root certificate file", func(t *testing.T) { - serverConfig := &ServerConfig{ - RootCACert: "./testdata/nofile.cert", - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "no such file or directory") - }) - - t.Run("fails with invalid client certificate file", func(t *testing.T) { - serverConfig := &ServerConfig{ - ClientCert: "./testdata/invalid.cert", - ClientKey: "./testdata/invalid.pem", - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "failed to find any PEM data") - }) - - t.Run("fails with non existing client certificate file", func(t *testing.T) { - serverConfig := &ServerConfig{ - ClientCert: "./testdata/nofile.cert", - ClientKey: "./testdata/parsable.pem", - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "no such file or directory") - }) - - t.Run("fails having no host but with valid root and client certificate values", func(t *testing.T) { - serverConfig := &ServerConfig{ - Host: "", - RootCACertValue: []string{validCert}, - ClientCertValue: validCert, - ClientKeyValue: validKey, - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "connect") - }) - - t.Run("fails with invalid base64 root certificate value", func(t *testing.T) { - serverConfig := &ServerConfig{ - RootCACertValue: []string{"invalid-certificate"}, - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "illegal base64 data") - }) - - t.Run("fails with invalid root certificate value", func(t *testing.T) { - serverConfig := &ServerConfig{ - RootCACertValue: []string{"aW52YWxpZC1jZXJ0aWZpY2F0ZQ=="}, - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "failed to append CA certificate") - }) - - t.Run("fails with invalid base64 client certificate value", func(t *testing.T) { - serverConfig := &ServerConfig{ - ClientCertValue: "invalid-certificate", - ClientKeyValue: validKey, - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "illegal base64 data") - }) - - t.Run("fails with invalid client certificate value", func(t *testing.T) { - serverConfig := &ServerConfig{ - ClientCertValue: validCert, - ClientKeyValue: "aW52YWxpZC1rZXk=", - } - server := New(serverConfig, &Config{}) - - err := server.Dial() - require.Error(t, err) - require.ErrorContains(t, err, "failed to find any PEM data") - }) -} - -func TestServer_Close(t *testing.T) { - t.Run("close the connection", func(t *testing.T) { - connection := &MockConnection{} - - server := &Server{ - Config: &ServerConfig{ - Attr: AttributeMap{}, - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: connection, - } - - assert.NotPanics(t, server.Close) - assert.True(t, connection.CloseCalled) - }) - - t.Run("panic if no connection", func(t *testing.T) { - server := &Server{ - Config: &ServerConfig{ - Attr: AttributeMap{}, - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: nil, - } - - assert.Panics(t, server.Close) - }) -} - -func TestServer_Users(t *testing.T) { - t.Run("one user", func(t *testing.T) { - conn := &MockConnection{} - entry := ldap.Entry{ - DN: "dn", Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"roelgerrits"}}, - {Name: "surname", Values: []string{"Gerrits"}}, - {Name: "email", Values: []string{"roel@test.com"}}, - {Name: "name", Values: []string{"Roel"}}, - {Name: "memberof", Values: []string{"admins"}}, - }} - result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}} - conn.setSearchResult(&result) - - // Set up attribute map without surname and email - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Attr: AttributeMap{ - Username: "username", - Name: "name", - MemberOf: "memberof", - }, - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: conn, - log: log.New("test-logger"), - } - - searchResult, err := server.Users([]string{"roelgerrits"}) - - require.NoError(t, err) - assert.NotNil(t, searchResult) - - // User should be searched in ldap - assert.True(t, conn.SearchCalled) - // No empty attributes should be added to the search request - assert.Len(t, conn.SearchAttributes, 3) - }) - - t.Run("error", func(t *testing.T) { - expected := errors.New("Killa-gorilla") - conn := &MockConnection{} - conn.setSearchError(expected) - - // Set up attribute map without surname and email - server := &Server{ - Config: &ServerConfig{ - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: conn, - log: log.New("test-logger"), - } - - _, err := server.Users([]string{"roelgerrits"}) - - assert.ErrorIs(t, err, expected) - }) - - t.Run("no user", func(t *testing.T) { - conn := &MockConnection{} - result := ldap.SearchResult{Entries: []*ldap.Entry{}} - conn.setSearchResult(&result) - - // Set up attribute map without surname and email - server := &Server{ - Config: &ServerConfig{ - SearchBaseDNs: []string{"BaseDNHere"}, - }, - Connection: conn, - log: log.New("test-logger"), - } - - searchResult, err := server.Users([]string{"roelgerrits"}) - - require.NoError(t, err) - assert.Empty(t, searchResult) - }) - - t.Run("multiple DNs", func(t *testing.T) { - conn := &MockConnection{} - serviceDN := "dc=svc,dc=example,dc=org" - serviceEntry := ldap.Entry{ - DN: "dn", Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"imgrenderer"}}, - {Name: "name", Values: []string{"Image renderer"}}, - }} - services := ldap.SearchResult{Entries: []*ldap.Entry{&serviceEntry}} - - userDN := "dc=users,dc=example,dc=org" - userEntry := ldap.Entry{ - DN: "dn", Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"grot"}}, - {Name: "name", Values: []string{"Grot"}}, - }} - users := ldap.SearchResult{Entries: []*ldap.Entry{&userEntry}} - - conn.setSearchFunc(func(request *ldap.SearchRequest) (*ldap.SearchResult, error) { - switch request.BaseDN { - case userDN: - return &users, nil - case serviceDN: - return &services, nil - default: - return nil, fmt.Errorf("test case not defined for baseDN: '%s'", request.BaseDN) - } - }) - - server := &Server{ - cfg: &Config{}, - Config: &ServerConfig{ - Attr: AttributeMap{ - Username: "username", - Name: "name", - }, - SearchBaseDNs: []string{serviceDN, userDN}, - }, - Connection: conn, - log: log.New("test-logger"), - } - - searchResult, err := server.Users([]string{"imgrenderer", "grot"}) - require.NoError(t, err) - - assert.Len(t, searchResult, 2) - }) - - t.Run("same user in multiple DNs", func(t *testing.T) { - conn := &MockConnection{} - firstDN := "dc=users1,dc=example,dc=org" - firstEntry := ldap.Entry{ - DN: "dn", Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"grot"}}, - {Name: "name", Values: []string{"Grot the First"}}, - }} - firsts := ldap.SearchResult{Entries: []*ldap.Entry{&firstEntry}} - - secondDN := "dc=users2,dc=example,dc=org" - secondEntry := ldap.Entry{ - DN: "dn", Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"grot"}}, - {Name: "name", Values: []string{"Grot the Second"}}, - }} - seconds := ldap.SearchResult{Entries: []*ldap.Entry{&secondEntry}} - - conn.setSearchFunc(func(request *ldap.SearchRequest) (*ldap.SearchResult, error) { - switch request.BaseDN { - case secondDN: - return &seconds, nil - case firstDN: - return &firsts, nil - default: - return nil, fmt.Errorf("test case not defined for baseDN: '%s'", request.BaseDN) - } - }) - - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Attr: AttributeMap{ - Username: "username", - Name: "name", - }, - SearchBaseDNs: []string{firstDN, secondDN}, - }, - Connection: conn, - log: log.New("test-logger"), - } - - res, err := server.Users([]string{"grot"}) - require.NoError(t, err) - require.Len(t, res, 1) - assert.Equal(t, "Grot the First", res[0].Name) - }) - - t.Run("org role mapping", func(t *testing.T) { - conn := &MockConnection{} - - usersOU := "ou=users,dc=example,dc=org" - grootDN := "dn=groot," + usersOU - grootSearch := ldap.SearchResult{Entries: []*ldap.Entry{{DN: grootDN, - Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"groot"}}, - {Name: "name", Values: []string{"I am Groot"}}, - }}}} - babyGrootDN := "dn=babygroot," + usersOU - babyGrootSearch := ldap.SearchResult{Entries: []*ldap.Entry{{DN: grootDN, - Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"babygroot"}}, - {Name: "name", Values: []string{"I am baby Groot"}}, - }}}} - peterDN := "dn=peter," + usersOU - peterSearch := ldap.SearchResult{Entries: []*ldap.Entry{{DN: peterDN, - Attributes: []*ldap.EntryAttribute{ - {Name: "username", Values: []string{"peter"}}, - {Name: "name", Values: []string{"Peter"}}, - }}}} - groupsOU := "ou=groups,dc=example,dc=org" - creaturesDN := "dn=creatures," + groupsOU - grootGroups := ldap.SearchResult{Entries: []*ldap.Entry{{DN: creaturesDN, - Attributes: []*ldap.EntryAttribute{ - {Name: "member", Values: []string{grootDN}}, - }}}, - } - babyCreaturesDN := "dn=babycreatures," + groupsOU - babyGrootGroups := ldap.SearchResult{Entries: []*ldap.Entry{{DN: babyCreaturesDN, - Attributes: []*ldap.EntryAttribute{ - {Name: "member", Values: []string{babyGrootDN}}, - }}}, - } - humansDN := "dn=humans," + groupsOU - peterGroups := ldap.SearchResult{Entries: []*ldap.Entry{{DN: humansDN, - Attributes: []*ldap.EntryAttribute{ - {Name: "member", Values: []string{peterDN}}, - }}}, - } - - conn.setSearchFunc(func(request *ldap.SearchRequest) (*ldap.SearchResult, error) { - switch request.BaseDN { - case usersOU: - switch request.Filter { - case "(|(username=groot))": - return &grootSearch, nil - case "(|(username=babygroot))": - return &babyGrootSearch, nil - case "(|(username=peter))": - return &peterSearch, nil - default: - return nil, fmt.Errorf("test case not defined for user filter: '%s'", request.Filter) - } - case groupsOU: - switch request.Filter { - case "(member=groot)": - return &grootGroups, nil - case "(member=babygroot)": - return &babyGrootGroups, nil - case "(member=peter)": - return &peterGroups, nil - default: - return nil, fmt.Errorf("test case not defined for group filter: '%s'", request.Filter) - } - default: - return nil, fmt.Errorf("test case not defined for baseDN: '%s'", request.BaseDN) - } - }) - - isGrafanaAdmin := true - cfg := &Config{ - Enabled: true, - } - - server := &Server{ - cfg: cfg, - Config: &ServerConfig{ - Attr: AttributeMap{ - Username: "username", - Name: "name", - }, - SearchBaseDNs: []string{usersOU}, - SearchFilter: "(username=%s)", - GroupSearchFilter: "(member=%s)", - GroupSearchBaseDNs: []string{groupsOU}, - Groups: []*GroupToOrgRole{ - { - GroupDN: creaturesDN, - OrgId: 2, - IsGrafanaAdmin: &isGrafanaAdmin, - OrgRole: "Admin", - }, - { - GroupDN: babyCreaturesDN, - OrgId: 2, - OrgRole: "Editor", - }, - }, - }, - Connection: conn, - log: log.New("test-logger"), - } - - t.Run("disable user with no mapping", func(t *testing.T) { - res, err := server.Users([]string{"peter"}) - require.NoError(t, err) - require.Len(t, res, 1) - require.Equal(t, "Peter", res[0].Name) - require.ElementsMatch(t, res[0].Groups, []string{humansDN}) - require.Empty(t, res[0].OrgRoles) - require.True(t, res[0].IsDisabled) - }) - t.Run("skip org role sync", func(t *testing.T) { - server.cfg.SkipOrgRoleSync = true - - res, err := server.Users([]string{"groot"}) - require.NoError(t, err) - require.Len(t, res, 1) - require.Equal(t, "I am Groot", res[0].Name) - require.ElementsMatch(t, res[0].Groups, []string{creaturesDN}) - require.Empty(t, res[0].OrgRoles) - require.False(t, res[0].IsDisabled) - }) - t.Run("sync org role", func(t *testing.T) { - server.cfg.SkipOrgRoleSync = false - res, err := server.Users([]string{"groot"}) - require.NoError(t, err) - require.Len(t, res, 1) - require.Equal(t, "I am Groot", res[0].Name) - require.ElementsMatch(t, res[0].Groups, []string{creaturesDN}) - require.Len(t, res[0].OrgRoles, 1) - role, mappingExist := res[0].OrgRoles[2] - require.True(t, mappingExist) - require.Equal(t, identity.RoleAdmin, role) - require.False(t, res[0].IsDisabled) - require.NotNil(t, res[0].IsGrafanaAdmin) - assert.True(t, *res[0].IsGrafanaAdmin) - }) - t.Run("set Grafana Admin to false by default", func(t *testing.T) { - res, err := server.Users([]string{"babygroot"}) - require.NoError(t, err) - require.Len(t, res, 1) - require.Equal(t, "I am baby Groot", res[0].Name) - require.ElementsMatch(t, res[0].Groups, []string{babyCreaturesDN}) - require.Len(t, res[0].OrgRoles, 1) - role, mappingExist := res[0].OrgRoles[2] - require.True(t, mappingExist) - require.Equal(t, identity.RoleEditor, role) - require.False(t, res[0].IsDisabled) - require.NotNil(t, res[0].IsGrafanaAdmin) - assert.False(t, *res[0].IsGrafanaAdmin) - }) - }) -} - -func TestServer_UserBind(t *testing.T) { - t.Run("use provided DN and password", func(t *testing.T) { - connection := &MockConnection{} - var actualUsername, actualPassword string - connection.BindProvider = func(username, password string) error { - actualUsername = username - actualPassword = password - return nil - } - server := &Server{ - Connection: connection, - Config: &ServerConfig{ - BindDN: "cn=admin,dc=grafana,dc=org", - }, - } - - dn := "cn=user,ou=users,dc=grafana,dc=org" - err := server.UserBind(dn, "pwd") - - require.NoError(t, err) - assert.Equal(t, dn, actualUsername) - assert.Equal(t, "pwd", actualPassword) - }) - - t.Run("error", func(t *testing.T) { - connection := &MockConnection{} - expected := &ldap.Error{ - ResultCode: uint16(25), - } - connection.BindProvider = func(username, password string) error { - return expected - } - server := &Server{ - Connection: connection, - Config: &ServerConfig{ - BindDN: "cn=%s,ou=users,dc=grafana,dc=org", - }, - log: log.New("test-logger"), - } - err := server.UserBind("user", "pwd") - assert.ErrorIs(t, err, expected) - }) -} - -func TestServer_AdminBind(t *testing.T) { - t.Run("use admin DN and password", func(t *testing.T) { - connection := &MockConnection{} - var actualUsername, actualPassword string - connection.BindProvider = func(username, password string) error { - actualUsername = username - actualPassword = password - return nil - } - - dn := "cn=admin,dc=grafana,dc=org" - - server := &Server{ - Connection: connection, - Config: &ServerConfig{ - BindPassword: "pwd", - BindDN: dn, - }, - } - - err := server.AdminBind() - require.NoError(t, err) - - assert.Equal(t, dn, actualUsername) - assert.Equal(t, "pwd", actualPassword) - }) - - t.Run("error", func(t *testing.T) { - connection := &MockConnection{} - expected := &ldap.Error{ - ResultCode: uint16(25), - } - connection.BindProvider = func(username, password string) error { - return expected - } - - dn := "cn=admin,dc=grafana,dc=org" - - server := &Server{ - Connection: connection, - Config: &ServerConfig{ - BindPassword: "pwd", - BindDN: dn, - }, - log: log.New("test-logger"), - } - - err := server.AdminBind() - assert.ErrorIs(t, err, expected) - }) -} diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index dbd4c0a14e485..86a3986be310c 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -1,5 +1,4 @@ import { css } from '@emotion/css'; -import { noop } from 'lodash'; import { memo, ReactNode } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { useLocation } from 'react-router-dom-v5-compat'; @@ -15,7 +14,6 @@ import { ToolbarButtonRow, ConfirmModal, Badge, - PageToolbar, } from '@grafana/ui'; import { updateNavIndex } from 'app/core/actions'; import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate'; @@ -54,9 +52,9 @@ const mapDispatchToProps = { updateNavIndex, }; -const mapStateToProps = (state: StoreState) => { - return { ...state.fnGlobalState, navIndex: state.navIndex }; -}; +const mapStateToProps = (state: StoreState) => ({ + navIndex: state.navIndex, +}); const connector = connect(mapStateToProps, mapDispatchToProps); @@ -277,26 +275,17 @@ export const DashNav = memo((props) => { }; const renderRightActions = () => { - const { dashboard, isFullscreen, kioskMode, FNDashboard, hideTimePicker } = props; + const { dashboard, isFullscreen, kioskMode, hideTimePicker } = props; const { canSave, canEdit, showSettings, canShare } = dashboard.meta; const { snapshot } = dashboard; const snapshotUrl = snapshot && snapshot.originalUrl; const buttons: ReactNode[] = []; - // const tvButton = config.featureToggles.topnav ? null : ( - // - // ); if (isPlaylistRunning()) { return [renderPlaylistControls(), renderTimeControls()]; } - if (kioskMode === KioskMode.TV || kioskMode === KioskMode.FN) { + if (kioskMode === KioskMode.TV) { return [renderTimeControls()]; } @@ -307,7 +296,6 @@ export const DashNav = memo((props) => { onClick={onOpenSnapshotOriginal} icon="link" key="button-snapshot" - isHidden={!!FNDashboard} /> ); } @@ -325,13 +313,14 @@ export const DashNav = memo((props) => { onDismiss: hideModal, }); }} - isHidden={!!FNDashboard} /> )} ); } + addCustomContent(dynamicDashNavActions.right, buttons); + if (showSettings) { buttons.push( ((props) => { icon="cog" onClick={onOpenSettings} key="button-settings" - isHidden={!!FNDashboard} /> ); } @@ -368,47 +356,16 @@ export const DashNav = memo((props) => { return buttons; }; - const { isFullscreen, title, folderTitle } = props; - - // let titleHref = ''; - // let parentHref = ''; - - // if (kioskMode !== KioskMode.FN && location !== undefined) { - // console.log( location, "inside location" ) - // this ensures the component rerenders when the location changes - // const location = useLocation() - // titleHref = locationUtil.getUrlForPartial(location, { search: 'open' }); - // parentHref = locationUtil.getUrlForPartial(location, { search: 'open', folder: 'current' }); - // } - - const onGoBack = isFullscreen ? onclose : undefined; - - if (config.featureToggles.topnav) { - return ( - - {renderLeftActions()} - - {renderRightActions()} - - } - /> - ); - } - return ( - - {renderRightActions()} - + + {renderLeftActions()} + + {renderRightActions()} + + } + /> ); }); diff --git a/public/app/features/dashboard/components/DashNav/ShareButton.tsx b/public/app/features/dashboard/components/DashNav/ShareButton.tsx index 5a73143687e9a..5254e1c2b673d 100644 --- a/public/app/features/dashboard/components/DashNav/ShareButton.tsx +++ b/public/app/features/dashboard/components/DashNav/ShareButton.tsx @@ -1,11 +1,18 @@ +import { useContext } from 'react'; + import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src'; import { locationService } from '@grafana/runtime'; -import { Button } from '@grafana/ui'; +import { Button, ModalsContext } from '@grafana/ui'; import { Trans } from 'app/core/internationalization'; import { DashboardModel } from 'app/features/dashboard/state'; import { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions'; +import { ShareModal } from '../ShareModal'; +import { shareDashboardType } from '../ShareModal/utils'; + export const ShareButton = ({ dashboard }: { dashboard: DashboardModel }) => { + const { showModal, hideModal } = useContext(ModalsContext); + return (
+ +
+ + [[if .GoogleTagManagerId]] + + [[if .GoogleTagManagerId]] + + + + [[end]] [[range $asset := .Assets.JSFiles]][[end]] \ No newline at end of file + })(window, document, 'script', 'dataLayer', '[[.GoogleTagManagerId]]'); + + + [[end]] + + [[range $asset := .Assets.JSFiles]] + + [[end]] + + + + diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 63cb0eeb134c4..cdc35f8aee136 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -106,20 +106,6 @@ module.exports = (env = {}) => { new MiniCssExtractPlugin({ filename: 'grafana.[name].[contenthash].css', }), - new HtmlWebpackPlugin({ - filename: path.resolve(__dirname, '../../public/views/error.html'), - template: path.resolve(__dirname, '../../public/views/error-template.html'), - inject: false, - chunksSortMode: 'none', - excludeChunks: ['dark', 'light', 'fn_dashboard'], - }), - new HtmlWebpackPlugin({ - filename: path.resolve(__dirname, '../../public/views/index.html'), - template: path.resolve(__dirname, '../../public/views/index-template.html'), - inject: false, - chunksSortMode: 'none', - excludeChunks: ['dark', 'light', 'fn_dashboard'], - }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/microfrontends/fn_dashboard/index.html'), template: path.resolve(__dirname, '../../public/views/index-microfrontend-template.html'), diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 383f927121374..8d9594e261a14 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -4,11 +4,10 @@ const browserslist = require('browserslist'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const { EsbuildPlugin } = require('esbuild-loader'); const { resolveToEsbuildTarget } = require('esbuild-plugin-browserslist'); -const ESLintPlugin = require('eslint-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); -const { DefinePlugin, EnvironmentPlugin } = require('webpack'); +const { EnvironmentPlugin } = require('webpack'); const WebpackAssetsManifest = require('webpack-assets-manifest'); const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); const { merge } = require('webpack-merge'); @@ -28,6 +27,7 @@ const esbuildOptions = { const envConfig = getEnvConfig(); +// using dev webpack for prod build to avoid css leak issues in microfrontends module.exports = (env = {}) => merge(common, { mode: 'production', @@ -77,25 +77,6 @@ module.exports = (env = {}) => new MiniCssExtractPlugin({ filename: 'grafana.[name].[contenthash].css', }), - new ESLintPlugin({ - cache: true, - lintDirtyModulesOnly: true, // don't lint on start, only lint changed files - extensions: ['.ts', '.tsx'], - }), - new HtmlWebpackPlugin({ - filename: path.resolve(__dirname, '../../public/views/error.html'), - template: path.resolve(__dirname, '../../public/views/error-template.html'), - inject: false, - chunksSortMode: 'none', - excludeChunks: ['dark', 'light', 'fn_dashboard'], - }), - new HtmlWebpackPlugin({ - filename: path.resolve(__dirname, '../../public/views/index.html'), - template: path.resolve(__dirname, '../../public/views/index-template.html'), - inject: false, - chunksSortMode: 'none', - excludeChunks: ['dark', 'light', 'fn_dashboard'], - }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/microfrontends/fn_dashboard/index.html'), template: path.resolve(__dirname, '../../public/views/index-microfrontend-template.html'), @@ -121,10 +102,7 @@ module.exports = (env = {}) => } }); }, - new EnvironmentPlugin({ - ...envConfig, - SHOULD_LOG: 'false', - }), + new EnvironmentPlugin(envConfig), new WebpackBar({ color: '#eb7b18', name: 'Grafana', diff --git a/yarn.lock b/yarn.lock index 1e08fe0d582da..71a87377eb2a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2051,7 +2051,7 @@ __metadata: languageName: node linkType: hard -"@emotion/is-prop-valid@npm:^1.2.0": +"@emotion/is-prop-valid@npm:^1.2.0, @emotion/is-prop-valid@npm:^1.3.0": version: 1.3.0 resolution: "@emotion/is-prop-valid@npm:1.3.0" dependencies: @@ -2095,7 +2095,7 @@ __metadata: languageName: node linkType: hard -"@emotion/react@npm:^11.8.1": +"@emotion/react@npm:^11.13.3, @emotion/react@npm:^11.8.1": version: 11.13.3 resolution: "@emotion/react@npm:11.13.3" dependencies: @@ -2129,7 +2129,7 @@ __metadata: languageName: node linkType: hard -"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.2.0, @emotion/serialize@npm:^1.3.1": +"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.2.0, @emotion/serialize@npm:^1.3.0, @emotion/serialize@npm:^1.3.1": version: 1.3.1 resolution: "@emotion/serialize@npm:1.3.1" dependencies: @@ -2156,6 +2156,26 @@ __metadata: languageName: node linkType: hard +"@emotion/styled@npm:^11.13.0": + version: 11.13.0 + resolution: "@emotion/styled@npm:11.13.0" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.12.0" + "@emotion/is-prop-valid": "npm:^1.3.0" + "@emotion/serialize": "npm:^1.3.0" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0" + "@emotion/utils": "npm:^1.4.0" + peerDependencies: + "@emotion/react": ^11.0.0-rc.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/5463a0f15fc12a9e20340f52df49461e948c3ae7e2dd763db0ff937b0b96dd4e82eed85cd15e24621efb3b097a095b88b01d60f50cf6f38fe3ab7db6e77f9615 + languageName: node + linkType: hard + "@emotion/stylis@npm:0.8.5": version: 0.8.5 resolution: "@emotion/stylis@npm:0.8.5" @@ -2850,7 +2870,7 @@ __metadata: languageName: node linkType: hard -"@floating-ui/react@npm:0.26.23": +"@floating-ui/react@npm:0.26.23, @floating-ui/react@npm:^0.26.2": version: 0.26.23 resolution: "@floating-ui/react@npm:0.26.23" dependencies: @@ -11700,6 +11720,13 @@ __metadata: languageName: node linkType: hard +"ace-builds@npm:^1.32.8": + version: 1.36.2 + resolution: "ace-builds@npm:1.36.2" + checksum: 10/66ea2af6c0671781b9f1d58efa84d3af1335d84f48e54e83b5d0518ddb70d2ebe3caf30fe6552ebc759e4da7b1789e717df165055e09169e37c55df4b5d3b78a + languageName: node + linkType: hard + "acorn-globals@npm:^7.0.0": version: 7.0.1 resolution: "acorn-globals@npm:7.0.1" @@ -13611,7 +13638,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.0.0, clsx@npm:^2.1.1": +"clsx@npm:^2.0.0, clsx@npm:^2.1.0, clsx@npm:^2.1.1": version: 2.1.1 resolution: "clsx@npm:2.1.1" checksum: 10/cdfb57fa6c7649bbff98d9028c2f0de2f91c86f551179541cf784b1cfdc1562dcb951955f46d54d930a3879931a980e32a46b598acaea274728dbe068deca919 @@ -15248,7 +15275,7 @@ __metadata: languageName: node linkType: hard -"date-fns@npm:3.6.0": +"date-fns@npm:3.6.0, date-fns@npm:^3.3.1": version: 3.6.0 resolution: "date-fns@npm:3.6.0" checksum: 10/cac35c58926a3b5d577082ff2b253612ec1c79eb6754fddef46b6a8e826501ea2cb346ecbd211205f1ba382ddd1f9d8c3f00bf433ad63cc3063454d294e3a6b8 @@ -15615,6 +15642,13 @@ __metadata: languageName: node linkType: hard +"diff-match-patch@npm:^1.0.5": + version: 1.0.5 + resolution: "diff-match-patch@npm:1.0.5" + checksum: 10/fd1ab417eba9559bda752a4dfc9a8ac73fa2ca8b146d29d153964b437168e301c09d8a688fae0cd81d32dc6508a4918a94614213c85df760793f44e245173bb6 + languageName: node + linkType: hard + "diff-sequences@npm:^27.5.1": version: 27.5.1 resolution: "diff-sequences@npm:27.5.1" @@ -18741,7 +18775,8 @@ __metadata: "@cypress/webpack-preprocessor": "npm:6.0.2" "@emotion/css": "npm:11.11.2" "@emotion/eslint-plugin": "npm:11.11.0" - "@emotion/react": "npm:11.11.4" + "@emotion/react": "npm:^11.13.3" + "@emotion/styled": "npm:^11.13.0" "@fingerprintjs/fingerprintjs": "npm:^3.4.2" "@floating-ui/react": "npm:0.26.23" "@formatjs/intl-durationformat": "npm:^0.2.4" @@ -18994,6 +19029,8 @@ __metadata: rc-tree: "npm:5.8.8" re-resizable: "npm:6.9.17" react: "npm:18.2.0" + react-ace: "npm:^12.0.0" + react-datepicker: "npm:^7.3.0" react-diff-viewer: "npm:^3.1.1" react-dom: "npm:18.2.0" react-draggable: "npm:4.4.6" @@ -22412,6 +22449,13 @@ __metadata: languageName: node linkType: hard +"lodash.isequal@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.isequal@npm:4.5.0" + checksum: 10/82fc58a83a1555f8df34ca9a2cd300995ff94018ac12cc47c349655f0ae1d4d92ba346db4c19bbfc90510764e0c00ddcc985a358bdcd4b3b965abf8f2a48a214 + languageName: node + linkType: hard + "lodash.ismatch@npm:^4.4.0": version: 4.4.0 resolution: "lodash.ismatch@npm:4.4.0" @@ -27071,6 +27115,22 @@ __metadata: languageName: node linkType: hard +"react-ace@npm:^12.0.0": + version: 12.0.0 + resolution: "react-ace@npm:12.0.0" + dependencies: + ace-builds: "npm:^1.32.8" + diff-match-patch: "npm:^1.0.5" + lodash.get: "npm:^4.4.2" + lodash.isequal: "npm:^4.5.0" + prop-types: "npm:^15.8.1" + peerDependencies: + react: ^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10/56bd138183f2ebf95abb5a506a7e1d1a12e5a1e72e3a39312ef0ee5b2fe0148b430d769f0fceb84c63050e31ea6e22681260a46bc7802cd2295d7679f0c51cbc + languageName: node + linkType: hard + "react-beautiful-dnd@npm:^13.1.1": version: 13.1.1 resolution: "react-beautiful-dnd@npm:13.1.1" @@ -27155,6 +27215,22 @@ __metadata: languageName: node linkType: hard +"react-datepicker@npm:^7.3.0": + version: 7.3.0 + resolution: "react-datepicker@npm:7.3.0" + dependencies: + "@floating-ui/react": "npm:^0.26.2" + clsx: "npm:^2.1.0" + date-fns: "npm:^3.3.1" + prop-types: "npm:^15.7.2" + react-onclickoutside: "npm:^6.13.0" + peerDependencies: + react: ^16.9.0 || ^17 || ^18 + react-dom: ^16.9.0 || ^17 || ^18 + checksum: 10/594e23086a9a3e5a84b25c4e96f1f4e379f0702e3407af54045177cb82a7d8f78f09599f5ae227e9cb902e79ebc70cc8b814ea0e500c28eeee9ce6f741039878 + languageName: node + linkType: hard + "react-debounce-input@npm:=3.3.0": version: 3.3.0 resolution: "react-debounce-input@npm:3.3.0" @@ -27519,6 +27595,16 @@ __metadata: languageName: node linkType: hard +"react-onclickoutside@npm:^6.13.0": + version: 6.13.1 + resolution: "react-onclickoutside@npm:6.13.1" + peerDependencies: + react: ^15.5.x || ^16.x || ^17.x || ^18.x + react-dom: ^15.5.x || ^16.x || ^17.x || ^18.x + checksum: 10/bc1f5813ad25d81602661848b19f0c15357b87e224ddf5abc2ac4502ffddbe7ee44688827b0522327868ae63ab229030d2a2f185007ecfe861f1128d3e5319e6 + languageName: node + linkType: hard + "react-popper-tooltip@npm:^4.4.2": version: 4.4.2 resolution: "react-popper-tooltip@npm:4.4.2"